WNDPROC处理事件更少的代码
Wndproc handling events less code
我想知道我是否有一种方法可以缩短此代码。我检查是否已经设置了功能,如果有的话,我会打电话给它这只是我的wndproc的一方面,它更大
LRESULT Base::WindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
switch (uMsg)
{
case WM_CREATE:
{
if (this->onCreate != NULL)
{
if (onCreate(hwnd, (LPCREATESTRUCT)lParam))
return 1;
}
}break;
case WM_DESTROY:
{
if (onDestroy != NULL)
{
if (onDestroy(hwnd))
return 1;
}
this->Destroy();
}break;
case WM_SIZE:
{
if (onSize != NULL)
{
if (onSize(hwnd, wParam, lParam))
return 1;
}
}break;
case WM_CLOSE:
{
if (onClose != NULL)
{
if (onClose(hwnd))
return 1;
}
}break;
default:
{
}break;
}
return ::DefWindowProc(hwnd, uMsg, wParam, lParam);
}
像这样定义的指针
LRESULT(*onCreate) (HWND, LPCREATESTRUCT);
我然后像这样添加它们
LRESULT onCreate(HWND, LPCREATESTRUCT)
{
return true;
}
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR pCmdLine, int nCmdShow)
{
Window mainWindow;
mainWindow.onCreate = onCreate;
return 0;
}
使用<WindowsX.h>
中定义的消息 - 裂缝宏。这实际上不会使代码运行更快,并且并不会真正导致代码行的净损失,但是它肯定会使代码易于阅读,这是重要的部分。没有人愿意查看1000行开关语句。另外,这些宏从WPARAM和LPARAM提取每条消息的参数,增强可读性,减少错误并简化您必须记住的内容。
宏非常简单,除了高科技外(它们在16位Windows日期都起源):
:#define HANDLE_MSG(hwnd, message, fn)
case (message): return HANDLE_##message((hwnd), (wParam), (lParam), (fn))
,但它们是针对所有最常见消息的预定义(您可以为他们省略的两到三条消息添加,如果您发现您需要它们),因此您不必处理丑陋。您只会得到不错的,可读的代码:
#include <Windows.h>
#include <WindowsX.h> // for the message cracker macros
...
void Base::OnClose(HWND hWnd)
{
// ...
}
BOOL Base::OnCreate(HWND hWnd, LPCREATESTRUCT lpCreateStruct)
{
// ...
return TRUE;
}
void Base::OnDestroy(HWND hWnd)
{
// ...
}
void Base::OnSize(HWND hWnd, UINT state, int cx, int cy)
{
// ...
}
LRESULT Base::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
HANDLE_MSG(hWnd, WM_CLOSE, OnClose);
HANDLE_MSG(hWnd, WM_CREATE, OnCreate);
HANDLE_MSG(hWnd, WM_DESTROY, OnDestroy);
HANDLE_MSG(hWnd, WM_SIZE, OnSize);
// TODO: Add more message crackers here to handle additional messages.
default:
return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
}
}
标头文件还包含注释,显示了处理程序功能的签名。但是,请查看HernánDiPietro的信息Cracker向导,以使您的生活更加轻松。它列出了所有消息,允许您将它们过滤到所需的消息,并将自动将模板代码复制到剪贴板!
为了避免基类中所有可能的特定(虚拟)消息处理程序的定义,您可以拥有一个处理程序的地图:
#include <unordered_map>
// Mokup windows.h
typedef intptr_t HWND;
typedef intptr_t LRESULT;
typedef intptr_t WPARAM;
typedef intptr_t LPARAM;
typedef unsigned UINT;
enum {
WM_CREATE
};
// Base
class WindowBase
{
public:
virtual ~WindowBase() {}
LRESULT WindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
// The complexity of finding an element in an unordered map
// is amortized O(1).
auto kv = window_procedures.find(uMsg);
if(kv != window_procedures.end()) {
auto procedure = kv->second;
return (this->*procedure)(hwnd, uMsg, wParam, lParam);
}
return 0; //::DefWindowProc(hwnd, uMsg, wParam, lParam);
}
protected:
typedef LRESULT (WindowBase::*window_procedure)(HWND, UINT msg, WPARAM, LPARAM);
template <typename Procedure>
void register_window_procedure(UINT msg, Procedure procedure) {
window_procedures[msg] = static_cast<window_procedure>(procedure);
}
private:
std::unordered_map<UINT, window_procedure> window_procedures;
};
// Test
#include <iostream>
class Window : public WindowBase
{
public:
Window() {
register_window_procedure(WM_CREATE, &Window::onCreate);
}
protected:
LRESULT onCreate(HWND, UINT msg, WPARAM, LPARAM) {
std::cout << "onCreaten";
return 0;
}
};
int main() {
Window w;
WindowBase* p = &w;
p->WindowProc(0, WM_CREATE, 0, 0);
}
注意:这不是使用独立消息处理程序遵循您的示例。如果需要,可以typedef LRESULT (*window_procedure)(HWND, UINT msg, WPARAM, LPARAM);
并相应地调整代码。但是,函数签名应包括一个额外的参数(例如:windowbase*),以保留上下文(除了hwnd之外),其中调用了该消息。
相关文章:
- 为什么需要与 WCHAR 相关的代码处理
- 来自API的错误代码..处理什么是好的做法
- 是否可以在QT GUI应用程序中处理事件时播放加载动画指示器?
- 指纹读取器 - 从 C# 代码创建事件处理程序到C++的问题
- 如果窗口服务被杀,如何处理事件
- GRPC C 称为PloteimionQueue关闭,但PostemionQueue.Next在有待处理事件时永远阻
- WNDPROC处理事件更少的代码
- C FLTK 1.3.2:最新的屏幕,处理事件和非障碍睡眠
- 在运行线程中处理事件
- 如何在Windows C++中处理事件
- 使用 EVT_NAVIGATION_KEY 处理事件不起作用
- 用于阻止代码处理的宏
- C++ 从另一个程序集创建 WPF 窗口的父级并处理事件
- 在QT OpenGL中处理事件
- 如何在QThread上处理事件
- Pro*C代码处理以解决ORA-01405:提取的列值为NULL
- 移动精灵和处理事件
- WinVerifyTrust错误代码处理
- 如何处理事件消息,同时使用chrome嵌入式框架(CEF)
- 处理事件从wxTextCtrl在wxFrame - c++ /wxWidgets