Find which dll / exe created a window.

Posted in Tip on March 23, 2008 by naveenraj
The GetWindowModuleFileName() functions can be used to find which exe or dll have created a window. But the problem with this function is that, it will not work across process.

When ever we create a window, we have to pass the an HINSTANCE into it. And later we can use GetWindowLong to get that HINSTANCE. Actually the HINSTANCE is noting but the HMODULE itself. So if we get the hinstance of a window, we can pass this handle to the
GetModuleFileNameEx() and simply get the name of the window from other processes also.

CString MyGetWindowModuleFileName( HANDLE hwindowhandle )
{
CString csModuleName;
DWORD dwProcessId;
GetWindowThreadProcessId( hwindowhandle, &dwProcessId );
HINSTANCEhModule = (HINSTANCE)GetWindowLong( hwindowhandle, GWL_HINSTANCE );
if(hModule == NULL)
{
return csModuleName;
}
HANDLE hProcess = OpenProcess(PROCESS_VM_READPROCESS_QUERY_INFORMATION, FALSE, dwProcessId );
if( hProcess == NULL )
{
return csModuleName;
}
BOOL bReturn = GetModuleFileNameEx( hProcess, hModule, csModuleName.GetBuffer( MAX_PATH), MAX_PATH );
csModuleName.ReleaseBuffer();
CloseHandle(hProcess);
return csModuleName;
}

Advertisements

WM_DEVICECHANGE problem

Posted in Bug on January 3, 2008 by naveenraj
In one our Projects at company, we used WM_DEVICECHANGE message to detect the arrival and removal of USB devices. The application was supposed to run on a machine in which will be running along with several other utility applications. Some months after the project delivery, client reported that, sometimes even if a USB device is plugged in, it is not detected. Problem problem…..

After some investigations we found that if we make the window a top-level window (HWND_TOPMOST), there is no such problem s. But what’s the relation between the z-order and the above problem. Later we got few more points to identify the relation.

1. The WM_DEVICECHANGE is send to all the top-level windows according to their z-order. That is the window at the top most position receives the message first, the only the window below it and so one.

2. If a window got a WM_DEVICECHANGE and if it didn’t process the message with in a period (in my machine I think it was 20 secs), the message will not reach to the subsequent windows under it.

Now everything became clear to us, some window whose z-order is greater than our application window might have hung or didn’t process the message within 20 seconds. Thus our window didn’t get a chance. Also when we made our window top level it will be one of the first window’s to get WM_DEVICECHANGE message so reducing the number of windows above it to get hung. How ever we didn’t find a proper solution for this and moved to an alternative method to detect device arrival and removal.

I think windows might not be using the BroadcastSystemMessage() function with the BSF_FORCEIFHUNG flag, while sending the WM_DEVICECHANGE message.

Bug in Rich Edit control

Posted in Bug on October 31, 2007 by naveenraj

Basically this not a vc++ bug. Its actually a bug in the RichEdit control so the bug belongs to windows.

Check the picture…

What you see inside the red circle is the caret of rich edit control. It passed the boundaries of rich edit control and moved to the dialog.

Step to reproduce.

1. Create a dialog based application and place a rich edit control on it.
2. Give the Multi line and Auto HSCROLL style.
3. Now run the application and click inside the rich edit, and keep on pressing space bar. You can see the caret crossing the boundary of rich edit and starts moving through the dialog.

This problem exists in vista and XP. But I didn’t find a place to report this bug to Microsoft. I searched the whole internet to find some one already reported this problem. But coudn’t find any. I dont know why such a problem haven’t been noticed for the past 12 years( 12 years because I think the problem exists in the rich edit of 95 also ).

Hide / Minimize dialog on startup

Posted in Tip on October 30, 2007 by naveenraj
Have you ever tried to minimize a dialog during the startup of a dialog based application? The problem is in a dialog based application, we will not get the control after the dialog is completely created. Even a call to ShowWindow() from the OnInitDialog() function, will not work. So what will we do if we got such a requriment? Well I got a simple technique for doing this by modifying the InitInstance() function of the app class.

The code for creating a dialog in the InitInstance() function will look like this.

CDialogBasedDlg dlg;
m_pMainWnd = &dlg;
INT_PTR nResponse = dlg.DoModal();

My idea is to change this code a little as follows..

CDialogBasedDlg dlg;
dlg.Create( CDialogBasedDlg::IDD );

dlg.ShowWindow( SW_HIDE );
m_pMainWnd = &dlg;
INT_PTR nResponse = dlg.RunModalLoop();

Actually inside the MFC framework, the DoModal() function calls the CreateDlgIndirect() and then RunModalLoop(). It also handles the tasks such as disabling the parent window etc. In our case the dialog itself is the parent window so do haven’t to worry about such things.