我正在研究一些MFC/C++视图对象子类,如下所示:
BOOL CCustomView::CreateView(DWORD dwStyle,
CDocument * pDocument,
CWnd * pParent,
String title)
{
...
CString className = AfxRegisterWndClass(CS_DBLCLKS,
::LoadCursor(NULL, IDC_IBEAM));
return Create(className, title, dwStyle,
rect, pParent, -1, &context);
}
虽然这对MFC应用程序编程来说很正常,但我不喜欢的是运行时窗口类名不是我自己选择的名称。如果以后,我想从另一个Win32应用程序中找到这个窗口,并按窗口类名找到窗口,我将不得不使用丑陋的"Afx:123:39843:39843:39843"字符串,实际上,我不知道这些窗口类名是否可以指望不变。我宁愿将窗口类更改为"CCustomView",但它仍然具有与上面创建的窗口类相同的行为。我该怎么做?
有更好的方法来解决您的问题。我使用的典型协议是:
- 在两个应用程序中使用
RegisterWindowMessage
注册窗口消息。消息名称应包含GUID以使其唯一 - 在应用程序A中,使用
PostMessage(HWND_BROADCAST, registeredMsg, idIWantToFindYou, HWNDofA)
将您的窗口句柄发布到所有顶级窗口。由于注册的消息有多种用途,并且您应该限制注册的消息数量,因此请使用idIWantTofindYou
来区分消息的不同命令 - 接收应用程序B现在拥有发送方的窗口句柄,并且可以建立连接(例如通过
PostMessage(HWNDofA, registeredMessage, idHereIsMyHWnd, HWNDofB)
此机制的优点是不会遇到无响应程序的问题。然而,"连接"并不是即时的,因此您必须更改程序流。或者,您可以使用EnumWindows
和SendMessageTimeout
来探测所有顶级窗口。
如果需要使用窗口类:
MFC指定的类名只是为了重用具有相同属性的窗口类。我不知道使用您自己的窗口类有任何问题。
因此,以下应该工作:
- 用所需属性填充
WNDCLASS
或WNDCLASSEX
- 使用
DefWindowProc
作为WNDPROC
(MFC就是这样做的,MFC的WNDPROC
是在创建窗口时设置的) - 使用
AfxRegisterClass
或RegisterClass
注册窗口类。AfxRegisterClass
检查该类是否已经注册,如果该类是从DLL注册的,则在卸载DLL时将注销该类。否则,它们大致相等