我可以有主窗口过程作为一个lambda在WinMain
can I have main window procedure as a lambda in WinMain?
我有一个简单的窗口应用程序,声明主窗口回调过程:
WNDCLASSEXW wcx;
/* ... */
wcx.lpfnWndProc = MainWndProc;
和WinMain
之后,我宣布LRESULT CALLBACK MainWndProc(HWND mainWindow, UINT msg, WPARAM wparam, LPARAM lparam) { /* ... */}
和一切都工作正常,但我想知道是否有可能有这个MainWndProc
作为lambda 内部 WinMain ?
你可以使用lambda,如果它没有捕获,那么它有一个隐式转换到函数指针:
#include <iostream>
typedef void (*func)();
static func some_func;
int global;
int main() {
some_func = [](){ std::cout << "Hellon"; }; // Fine
some_func();
int local;
some_func = [&](){ local = 1; }; // Illegal - No conversion
some_func = [](){ global = 1; }; // Fine
}
真正的问题是,在没有捕获的情况下,你能在lambda中做多少有用的回调。您仍然可以使用"全局变量",就像您使用常规函数作为回调函数一样。
您可以使用lambda,但它不能捕获[]中的任何变量,例如:
wc.lpfnWndProc=[](HWND h, UINT m, WPARAM w, LPARAM l)->LRESULT
{
if (m==WM_CLOSE)
PostQuitMessage(0);
else
return DefWindowProc(h,m,w,l);
return 0;
};
可在Visual c++ 2012中使用
对于包装类,您可以使用将"this"指针存储为HWND上的货物数据的老技术。
该技术的一个限制是,您不能处理在WM_CREATE之前到达的任何消息,WM_CREATE是携带creation参数的消息(只有少数这些早期消息,而且它们相当奇特)。
#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;
}
相关文章:
- 如何将 lambda 函数作为参数发送到另一个函数
- C++ 一个lambda浅拷贝const Type&如果它被赋予一个命名捕获,如[copy=val](){}?
- 创建一个带有 lambda 的 std::函数,而不知道函数的参数
- 如何参数化用作另一个 lambda 参数的 lambda
- 是否可以将带有捕获和参数的 lambda 传递给另一个函数?如果是这样,如何?
- C++:实现一个接收lambda作为输入的高阶函数
- 带有自定义deleter的std::unique_ptr对象的大小(一个由ref捕获的lambda)
- c++:为什么一个特定的参数必须由lambda中的值捕获
- 在另一个 lambda 中捕获一个 lambda 可能会违反 const 限定符
- 如何从另一个lambda函数调用lambda函数
- 通过捕获作为另一个lambda的参数将lambda传递
- 将函数参数传递给另一个lambda
- 在另一个lambda中调用catch块中捕获的lambda会产生GCC错误
- 将指向lambda函数的指针赋值给指向另一个lambda函数的指针
- 如何返回一个lambda函数
- c++ 11变量捕获与lambda内部的另一个lambda
- 给定一个lambda捕获,哪些规则决定结果闭包成员的类型
- 我如何创建一个lambda函数来匹配boost::函数参数,而不使用c++ 0x
- Boost Lambda/Phoenix-如何处理返回另一个Lambda的Lambda
- 我可以有主窗口过程作为一个lambda在WinMain