Prev: Runtime error-help plz.
Next: uafxcw.lib(dllmodul.obj) : error LNK2005: _DllMain@12 already defined
From: Headache on 29 Jun 2007 06:54 Hello, I'm using a program to drive a GUI. For simple messages such as LB_SETSEL the PostMessage API works fine. I use SendMessage for WM_NOTIFY as it takes the address of a local NMITEMACTIVATE structure. I've tried this with very simple cases. Using Spy++ to obtain the window handles and to observe the messages I never see the WM_NOTIFY message neither does my simple handler in my simple client get invoked. I'm assuming window handles are globally unique. Here is my code on the testing side: void CTelusDlg::ClickOnListControl(HWND hWndParent, HWND hWndListCtrl, int iItem, int iSubItem) { NMITEMACTIVATE nmia; ::ZeroMemory(&nmia, sizeof(NMITEMACTIVATE)); // Set up header nmia.hdr.code = NM_CLICK; nmia.hdr.hwndFrom = hWndListCtrl; nmia.hdr.idFrom = ::GetDlgCtrlID(hWndListCtrl); // value is 426 // Setup item and subitem nmia.iItem = iItem; nmia.iSubItem = iSubItem; if ( ! ::SendMessage(hWndParent, WM_NOTIFY, nmia.hdr.idFrom, (LPARAM)&nmia) ) { DWORD dwError = ::GetLastError(); LPTSTR lpBuffer; ::FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwError, MAKELANGID(LANG_NEUTRAL, SUBLANG_SYS_DEFAULT), (LPTSTR)&lpBuffer, 0, NULL); ::AfxMessageBox(lpBuffer); ::LocalFree(lpBuffer); } } Here's the other side: BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) ON_WM_CREATE() ON_NOTIFY(NM_CLICK, 426, OnClick) END_MESSAGE_MAP() void CMainFrame::OnClick(NMHDR *pNMHDR, LRESULT* pResult) { ::AfxMessageBox(_T("Hurrah!!")); ASSERT(NM_CLICK == pNMHDR->code); NMITEMACTIVATE *pNMIA = (NMITEMACTIVATE *)pNMHDR; *pResult = 1; } I'm beginning to think that something chokes WM_NOTIFY messages when they're sent to windows in different processes. Am I right or has somebody managed this? Is there a workaround?
From: Scott McPhillips [MVP] on 29 Jun 2007 09:19 Headache wrote: > Hello, > > I'm using a program to drive a GUI. For simple messages such as > LB_SETSEL the PostMessage API works fine. I use SendMessage for > WM_NOTIFY as it takes the address of a local NMITEMACTIVATE structure. An address in your process is useless in another process. So even if the message was passed by Windows it would not contain a valid pointer. I don't know if Windows suppresses such a cross-process WM_NOTIFY, but it would be a real good idea if it does. One option that you could use is to send the WM_COPYDATA message to the other process. Windows provides support for this message by copying the passed data into the receiving process' memory. -- Scott McPhillips [MVP VC++]
From: David Ching on 29 Jun 2007 17:51 "Scott McPhillips [MVP]" <org-dot-mvps-at-scottmcp> wrote in message news:K5adnVn9ws6emhjbnZ2dnUVZ_gCdnZ2d(a)comcast.com... > Headache wrote: >> Hello, >> >> I'm using a program to drive a GUI. For simple messages such as >> LB_SETSEL the PostMessage API works fine. I use SendMessage for >> WM_NOTIFY as it takes the address of a local NMITEMACTIVATE structure. > > An address in your process is useless in another process. So even if the > message was passed by Windows it would not contain a valid pointer. I > don't know if Windows suppresses such a cross-process WM_NOTIFY, but it > would be a real good idea if it does. > > One option that you could use is to send the WM_COPYDATA message to the > other process. Windows provides support for this message by copying the > passed data into the receiving process' memory. > > -- To add to Scott's thought that passing fixed addresses to another process is wrong, see http://groups.google.com/group/microsoft.public.vc.mfc/browse_frm/thread/40c00794fa444323/291326274362ef36?lnk=st&q=dcsoft+sendmessageremote&rnum=1#291326274362ef36 which discusses my SendMessageRemote() function which sounds ideal for your situation. -- David
From: Joseph M. Newcomer on 1 Jul 2007 00:18 Really, really Bad Idea. Won't work, don't even try. You are passing a pointer to some other process, and the pointer is a meaningless integer. to make this work, you have to have a hook DLL injected into the target, send a customized message, or do really complicated things to retrieve the data from the other process. The simplest solution is to assume this is impossible. However, someone else has posted code that does this by DLL injection so you might check the archives. Window handles are global but pointers definitely are not, and so you can't send a WM_NOTIFY as you are trying to do because the pointer is a pointer to some other process. this is why OLE automation was invented. joe On Fri, 29 Jun 2007 03:54:06 -0700, Headache <rquirk(a)tandbergtv.com> wrote: >Hello, > >I'm using a program to drive a GUI. For simple messages such as >LB_SETSEL the PostMessage API works fine. I use SendMessage for >WM_NOTIFY as it takes the address of a local NMITEMACTIVATE structure. >I've tried this with very simple cases. Using Spy++ to obtain the >window handles and to observe the messages I never see the WM_NOTIFY >message neither does my simple handler in my simple client get >invoked. I'm assuming window handles are globally unique. Here is my >code on the testing side: > >void CTelusDlg::ClickOnListControl(HWND hWndParent, HWND hWndListCtrl, >int iItem, int iSubItem) >{ > NMITEMACTIVATE nmia; > ::ZeroMemory(&nmia, sizeof(NMITEMACTIVATE)); > // Set up header > nmia.hdr.code = NM_CLICK; > nmia.hdr.hwndFrom = hWndListCtrl; > nmia.hdr.idFrom = ::GetDlgCtrlID(hWndListCtrl); // value is 426 > // Setup item and subitem > nmia.iItem = iItem; > nmia.iSubItem = iSubItem; > if ( ! ::SendMessage(hWndParent, WM_NOTIFY, nmia.hdr.idFrom, >(LPARAM)&nmia) ) > { > DWORD dwError = ::GetLastError(); > LPTSTR lpBuffer; > ::FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | >FORMAT_MESSAGE_FROM_SYSTEM, > NULL, > dwError, > MAKELANGID(LANG_NEUTRAL, SUBLANG_SYS_DEFAULT), > (LPTSTR)&lpBuffer, > 0, > NULL); > ::AfxMessageBox(lpBuffer); > ::LocalFree(lpBuffer); > } >} > >Here's the other side: > >BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) > ON_WM_CREATE() > ON_NOTIFY(NM_CLICK, 426, OnClick) >END_MESSAGE_MAP() > >void CMainFrame::OnClick(NMHDR *pNMHDR, LRESULT* pResult) >{ > ::AfxMessageBox(_T("Hurrah!!")); > ASSERT(NM_CLICK == pNMHDR->code); > > NMITEMACTIVATE *pNMIA = (NMITEMACTIVATE *)pNMHDR; > > *pResult = 1; >} > > >I'm beginning to think that something chokes WM_NOTIFY messages when >they're sent to windows in different processes. Am I right or has >somebody managed this? Is there a workaround? Joseph M. Newcomer [MVP] email: newcomer(a)flounder.com Web: http://www.flounder.com MVP Tips: http://www.flounder.com/mvp_tips.htm
From: David Ching on 1 Jul 2007 00:36 "Joseph M. Newcomer" <newcomer(a)flounder.com> wrote in message news:0iae83tncd7dasjl3rq18e67c4v272g38h(a)4ax.com... > Window handles are global but pointers definitely are not, and so you > can't send a > WM_NOTIFY as you are trying to do because the pointer is a pointer to some > other process. > > this is why OLE automation was invented. I wonder why Windows takes care of marshalling pointers for some messages, such as WM_GETTEXT, but not for others. For example, SendMessage(WM_GETTEXT, ...) does work across processes. It seems if they marshalled some messages they would marshall all of them. I've heard the rule is messages below WM_USER are marshalled, but not others, but have not confirmed this. -- David
|
Next
|
Last
Pages: 1 2 3 4 Prev: Runtime error-help plz. Next: uafxcw.lib(dllmodul.obj) : error LNK2005: _DllMain@12 already defined |