使用包装类,您可以使用将“this”指针作为货物数据存储在 HWND 上的旧技术来实现。
这种技术的一个限制是您不能处理在 WM_CREATE 之前到达的任何消息,WM_CREATE 是带有创建参数的消息(这些早期消息中只有少数,而且它们非常奇特)。
#pragma once
// LambdaWindow.h -- Lambda Window utility
#include <windows.h>
#include <tchar.h>
#include <functional>
class LambdaWindow
{
public:
typedef
std::function<LRESULT(HWND h, UINT m, WPARAM w, LPARAM l)>
WindowProcFunction;
public:
LambdaWindow(const WindowProcFunction &pfn) : fn(pfn) { }
virtual ~LambdaWindow() { }
static LRESULT CALLBACK Stub(HWND h, UINT m, WPARAM w, LPARAM l)
{
LambdaWindow *pThis = (LambdaWindow *)GetWindowLongPtr(h, GWLP_USERDATA);
if (pThis)
{
return pThis->fn(h, m, w, l);
}
else if (m == WM_CREATE)
{
pThis = (LambdaWindow *)(((CREATESTRUCT *)l)->lpCreateParams);
SetWindowLongPtr(h, GWLP_USERDATA, (LONG_PTR)pThis);
return pThis->fn(h, m, w, l);
}
return DefWindowProc(h, m, w, l);
}
private:
WindowProcFunction fn;
};
上述实用程序的示例使用:
#include "LambdaWindow.h"
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
HWND wnd;
TCHAR testText[] = _T("Some Text");
RECT textLocation = { 10, 10, 150, 30 };
WNDCLASS wc = { 0 };
wc.lpfnWndProc = LambdaWindow::Stub;
wc.hInstance = hInstance;
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszClassName = L"minwindowsapp";
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
LambdaWindow wlambda =
[&](HWND h, UINT m, WPARAM w, LPARAM l)->LRESULT
{
switch (m)
{
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc;
hdc = BeginPaint(h, &ps);
DrawText(hdc, testText, -1,
&textLocation, DT_CENTER| DT_VCENTER );
EndPaint(h, &ps);
}
break;
case WM_CLOSE:
PostQuitMessage(0);
break;
default:
return DefWindowProc(h, m, w, l);
}
return 0;
};
if (RegisterClass(&wc))
{
wnd = CreateWindow(wc.lpszClassName,
L"Minimal Windows Application",
WS_OVERLAPPEDWINDOW,
0, 0, 640, 480, NULL, NULL, hInstance, &wlambda);
if (wnd)
{
MSG msg;
ShowWindow(wnd, nCmdShow);
UpdateWindow(wnd);
while (GetMessage(&msg, NULL, 0, 0) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
return 0;
}