Could anyone help to how to deal with "SwitchToThisWindow" on the process which from rundll32.exe? - rundll32

Could anyone help to how to deal with "SwitchToThisWindow" on the process which from rundll32.exe? thanks.
As below image: “Internet Properties” is under “Rundll32”, I have PID 3368 for rundll32.exe and use below code to put the process on top. But cannot switch “Internet Properties” to top.
Process process = Process.GetProcessById(pid);
SwitchToThisWindow(process.MainWindowHandle, true);
private static extern void SwitchToThisWindow(IntPtr hWnd, bool turnon);

Related

Why does c++ send WM_DRAWITEM to the parent process?

I started recently learning C++ and WinAPI, I want to be able to create my own programs
I am subclassing a button (into separate file, because I like things clean and organized - is that a bad idea?), because I want to have few of the kind with same parameters. I also want to draw it, and the question that pops to my mind is: wouldn't it be better to have it all in the class file? Meaning all parameters including custom draw. It is annoying to go to main file to change the looks and set all other parameters in the class file. I use codeblocks.
EDIT (explanation):
#include <Windows.h>
#include <Winuser.h>
#include "CustomButton.h"
/*global vars*/
WNDPROC CustomButton::CustomButtonLongPtr;
/*functions*/
LRESULT CALLBACK CustomButtonProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
CustomButton * CustomButton::CreateCustomButton(HINSTANCE hInstance, HWND hwnd, int pos_x, int pos_y, int width, int height)
{
CustomButton * p_CustomButton = new CustomButton;
HWND customButton = CreateWindowEx(0, "BUTTON", "OK", WS_VISIBLE | WS_CHILD | BS_OWNERDRAW, pos_x, pos_y, width, height, hwnd, (HMENU)200, (HINSTANCE)GetWindowLong(hwnd, GWLP_HINSTANCE), p_CustomButton);
if(customButton == NULL)
{
delete p_CustomButton;
MessageBox(NULL, "Problem creating the Search box.", "Error", 0);
return 0;
}
CustomButton::CustomButtonLongPtr = (WNDPROC)SetWindowLongPtr(customButton, GWLP_WNDPROC, (LONG_PTR)&CustomButton::CustomButtonProc);
return p_CustomButton;
}
I want to use WM_DRAWITEM for this button in CustomButtonProc and I am wondering why did the developers think that it would be smarted to allow to use it only in parent WinProc.
This is a little complicated to explain.
You're probably coming from a background where you plug a function into an outlet to handle events, something like
extern void onClicked(void);
button->OnClicked = onClicked;
And while it's fully possible for Windows to have done this from the start, you have to remember that Windows was originally designed to run on systems with severely limited memory, so it was important that controls not waste memory. And there are a lot of events you can get from a button:
void (*OnClicked)(void);
void (*OnDoubleClicked)(void);
void (*OnDisabled)(void);
void (*OnHighlight)(void);
void (*OnKillFocus)(void);
void (*OnPaint)(void);
void (*OnSetFocus)(void);
void (*OnUnhighlight)(void);
void (*OnUnpushed)(void);
HBRUSH (*OnCtlColorButton)(void);
Having these for every button in your program — that is, push buttons, checkboxes, radio buttons, and groupboxes — with most of them likely to be unused would just be a massive waste of memory.
Because Windows needs a way to communicate between the system and a window and between windows, Microsoft decided to create a message-passing interface where each message had a 16-bit code and two pointer-sized (originally one 32-bit and one 16-bit) parameters and a pointer-sized return value. And there aren't a lot of messages that Windows needs for itself, giving both window classes and the application a lot of real estate for using messages to communicate. So why not use a message to signal the event?
Using a message avoids the waste of memory while still allowing the button to pass data to and return data from its target window. So the logic follows that all a button would need to do is
/* this is not the correct syntax but let's use it for expository purposes */
#define BN_CLICKED someNumberHere
case WM_LBUTTONUP:
SendMessage(GetParent(hwnd), BN_CLICKED, hwnd);
break;
and the parent would handle that:
case BN_CLICKED:
if (whichButton == button1)
doButton1Stuff();
break;
No wasted memory, but still flexible and extensible. And even more importantly, also binary-compatible: if more events were added later, the size of the function pointer table would need to change, and newer programs that tried to use newer events on older systems would clobber random memory. With messages, these programs would just have dead code.
Now why send the message to the parent? If we view windows as communication endpoints, then this is obvious: you want the button to tell its parent that it was clicked because you're communicating that the button was clicked!
But more important, you didn't write the button's window procedure. Microsoft did, and they provide the same one to every program. If you could handle the message in the button procedure, where would you put it? You can't change the button procedure, after all.
(Nowadays we have something called "subclassing" which allows you to override a single window's window procedure to do custom processing. It's not used for event handling because it's more work than just sending up to the parent.)
All of this extends to custom draw; just substitute "custom draw" for "clicked" and it should still make sense. Hopefully this explanation was clear, even with that mental substitution.
If you want, you can write your own facility to handle events in the function pointer way. Keep a map of window handles to event functions and call a global dispatch function in all your window procedures to handle the event messages WM_COMMAND, WM_NOTIFY, and (for trackbars) WM_HSCROLL and WM_VSCROLL. How you do this is up to you, but think about whether you really want to do it this way; sometimes it's necessary, but sometimes it isn't. If you do, remember to provide a way to pass arbitrary data to the event function that's decided at event connection time, so the event handler can do something reasonable without relying on global state.
Thanks to comments by RemyLebeau and IInspectable I was able to also find solution to my frustration, which I am going to explain here for anybody else who's scratching their heads over this very issue.
This solution does not require VCL nor any component from Visual Studio and such.
First define your own custom message, in the way that you can reach it inside WndProc:
#define MY_DRAWITEM (WM_APP+1)
UINT uDrawButtonMsg = RegisterWindowMessage(_T("MY_DRAWITEM"));
Then find out what number it is assigned:
std::cout << uDrawButtonMsg; //for example 49648
And send this message from WndProc to your subclassed control from any message you wish, for example WM_DRAWITEM:
case WM_DRAWITEM:
{
::SendMessage(p_CustomButton->customButton, uDrawButtonMsg, wParam, lParam);
break;
}
And then in your subclass just catch the message by the 5 digit number you looked for while ago:
if(49648 == uMsg)
{
//do your DRAWITEM stuff here
}
Thanks to everybody who contributed to this article helping with exaplanation, tips and also historical background!

c++ mfc: update HWND through a control box

Can anyone help me how I update a HWND value through an edit control or any other kind of text box? I tried the following
void ChwndtestDlg::OnBnClickedButton1()
{
TCHAR thebuffer[100];
HWND thetext = (HWND)thebuffer;
GetDlgItemText(IDC_EDITWINDOW, thebuffer, 100);
::SendMessage(thetext,WM_SETTEXT,0,(LPARAM)L"hello");
}
But, that does not work! I'm new to all of this, and I'll be grateful for any help. Please bear in mind that I already know about enumwindows, and I have already successfully changed text in another program from my program, but I want to actually update the HWND in my edit control. It is supposed to work like so...
program 2's current hwnd = 0x00000:
open my program -> open program #2 -> input 0x00000 into textbox in my program -> click button in my program to update the hwnd value -> input text in my programs text editor -> text goes to program 2's text editor. I'm aware that there are other ways of doing this, but I would really like to do it the way I have described. Thanks in advance. I found a similar question, but the answer was to use enumwindows, but I don't want to use that.
You are typecasting the TCHAR[] itself to an HWND. That will never work. You need to extract the TCHAR[] text from the edit control, then use _stscanf() or similar parsing function to convert that text value to an integer which can be typecasted to an HWND, then assign your other text to that HWND as needed.
For example:
void ChwndtestDlg::OnBnClickedButton1()
{
CString sWnd;
if (GetDlgItemText(IDC_HWNDEDIT, sWnd) > 0)
{
HWND hWnd;
if (_stscanf((LPTSTR)sWnd, _T("%p"), &hWnd) == 1)
{
CString sText;
GetDlgItemText(IDC_TEXTEDIT, sText);
::SendMessage(hWnd, WM_SETTEXT, 0, (LPARAM)(LPTSTR)sText);
}
}
}

execute program while window handled mfc

I want to make program work while handle is available. I thinking about setting timer on initialization... and insert all source of program in to it, but if I got lost handle when program processing in while loop it will not let me close dialog box immediately.
BOOL WaitProcessDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
SetTimer(IDC_PROGRESS1, 0, NULL);
return TRUE;
}
void WaitProcessDlg::OnTimer(UINT nIDEvent)
{
if(::FindWindow(NULL, str)){
tempHWND = ::FindWindow(NULL, str);
while(tempHWND){
----------------------->>>>>>>>>>>> A LOT OF CODING <<<<<<<<<<<<<<<<----------------------
}
EndDialog( 0 );
KillTimer(IDC_PROGRESS1);
}
CDialog::OnTimer(nIDEvent);
}
So my question is what the best way to close dialog when handle of external application may lost, maybe insert thread or there are any other way to do that?
It sounds like you need a windows hook.
http://msdn.microsoft.com/en-us/library/windows/desktop/ms644959(v=vs.85).aspx#whgetmessagehook
with WH_GETMESSAGE you get to see the windows events being processed by the other application's window, you could then wait for the WM_CLOSE to show up, and kill your dialog.

Getting Window info from its HWND

I have this code:
HWND WindowHandle;
WindowHandle = FindWindowA( WindowClass, WindowName );
if( WindowHandle != NULL)
{
// here I want to populate a listbox with the window's information like
// its process name and PID, executable file name, and its window title.
}
I already know how to get the Window Title, with SendMessage(); and WM_GETTEXT, but I want to know how to get it's process name and PID, and also the executable file location and name.
Could anyone help me?
Please note that I am working with C++ MFC.
Windows offers a function called GetWindowThreadProcessId.
It sounds like what you want.
Disclaimer: I haven't used it.
You can find the PID in PROCESS_INFORMATION. Just declare say: PROCESS_INFORMATION pi and access PID like this: pi.hProcesss pi.dwProcessId.

FindWindow is not working?

I just want to know why this code is not working?
HWND hWnds = FindWindow(NULL,(LPCTSTR)"Calculator");
It always returns NULL for the hWnds....
Any idea how to fix this? Thank you :)
Dont cast the string.
HWND hWnds = FindWindow(NULL,_T("Calculator"));
Make a folder named 'Calculator' and enter into it using Windows Explorer.
Now run your program - wrong window handle would be returned!
Using Spy++ on Windows 7, I found out class-name of Calculator window to be: CalcFrame.
Try using this:
HWND hWnds = FindWindow(_T("CalcFrame"), NULL);