【发布时间】:2015-07-19 18:46:48
【问题描述】:
我正在尝试使用 WINAPI 来实现作为自定义类成员的无模式对话框窗口的过程。我不确定这是否可能,但我希望有人知道一种方法。目标是拥有一个可以访问自定义类的成员变量的过程
我知道使用普通窗口是可能的。 示例:
//MyClass.h
class MyClass
{
public:
bool init( ... )
static LRESULT CALLBACK redirect(HWND hWnd, UINT msg,
LPARAM lParam, WPARAM wParam);
LRESULT myWndProc(HWND hWnd, UINT msg,
LPARAM lParam, WPARAM wParam);
private:
HWND m_MainHwnd;
}
通过定义一个将指针重定向到非静态实际过程处理的静态成员函数,该过程可以是一个成员函数:
//MyClass.cpp
MyClass::init( ... )
{
//Create the window class for the main Window//
m_windowed = windowed;
WNDCLASSEX wc; //Create a new extended windows class
wc.cbSize = sizeof(WNDCLASSEX); //Size of our windows class
wc.style = CS_HREDRAW | CS_VREDRAW; //class styles
wc.lpfnWndProc = MyClass::redirect; //Default windows procedure function
wc.cbClsExtra = NULL; //Extra bytes after our wc structure
wc.cbWndExtra = NULL; //Extra bytes after our windows instance
wc.hInstance = hInstance; //Instance to current application
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); //Title bar Icon
wc.hCursor = LoadCursor(NULL, IDC_ARROW); //Default mouse Icon
wc.hbrBackground = CreateSolidBrush(0xFFFFFF); //Window bg color
wc.lpszMenuName = NULL; //Name of the menu attached to our window
wc.lpszClassName = m_windowName; //Name of our windows class
wc.hIconSm = LoadIcon(NULL, IDI_WINLOGO); //Icon in your taskbar
if (!RegisterClassEx(&wc)) //Register our windows class
{
//if registration failed, display error
MessageBox(NULL, "Error registering Main Window class",
"Error", MB_OK | MB_ICONERROR);
return false;
}
m_MainHwnd = CreateWindowEx( //Create our Extended Window
NULL, //Extended style
m_windowName, //Name of our windows class
m_windowName, //Name in the title bar of our window
WS_OVERLAPPEDWINDOW | WS_VISIBLE, //style of our window | Make it visible on showWindow cmd
30, 30, //Top left corner of window
width, //Width of our window
height, //Height of our window
NULL, //Handle to parent window
NULL, //Handle to a Menu
hInstance, //Specifies instance of current program
this //used for an MDI client window
);
}
查看 WNDCLASSEX 中设置中的行:wc.lpfnWndProc = MyClass::redirect;?这是有效的,因为重定向静态函数的实现如下:
MyClass::redirect(HWND hwnd, UINT msg, LPARAM lParam, WPARAM wParam)
{
if (msg == WM_CREATE) SetWindowLongPtr(hwnd, GWL_USERDATA, (LONG_PTR)((CREATESTRUCT FAR *)lParam)->lpCreateParams);
MyClass * pObject = (MyClass*)((LONG_PTR)GetWindowLongPtr(hwnd, GWL_USERDATA));
if (pObject) return pObject->MyWndProc(hwnd, msg, wParam, lParam);
//return the message for windows to handle it
return DefWindowProc(hwnd,
msg,
wParam,
lParam);
};
这使您可以像任何其他成员方法一样实现 MyWndProc ( ... )。
现在!我真的希望能够对我的无模式对话框做同样的事情——因为它知道“MyClass”的成员变量是相当重要的。另外 - 我喜欢我可以设计它并按照我的喜好重新设计它(如果我必须使用普通窗口 - 用代码设计它会很乏味。)
有可能吗?
提前谢谢你!
【问题讨论】: