C++ 自定义窗口进程在单独的文件中
我目前正在学习winapi,希望获得一些关于如何使用不同窗口过程设置自定义控件的建议 假设我有20个按钮。我希望鼠标悬停在每个按钮上时,每个按钮的响应都不同。比方说,“退出”按钮在悬停时绘制一个红色矩形,或者在其他按钮悬停时绘制一个蓝色矩形 因此,我设置了一个自定义控制过程,用于处理鼠标单击、鼠标悬停等操作,并存储在C++ 自定义窗口进程在单独的文件中,c++,winapi,global-variables,subclassing,C++,Winapi,Global Variables,Subclassing,我目前正在学习winapi,希望获得一些关于如何使用不同窗口过程设置自定义控件的建议 假设我有20个按钮。我希望鼠标悬停在每个按钮上时,每个按钮的响应都不同。比方说,“退出”按钮在悬停时绘制一个红色矩形,或者在其他按钮悬停时绘制一个蓝色矩形 因此,我设置了一个自定义控制过程,用于处理鼠标单击、鼠标悬停等操作,并存储在custom.cpp中。在main.cpp中,有一个MainProc(),它使用 CustomProcHandler = (WNDPROC)SetWindowLong(hwndBut
custom.cpp
中。在main.cpp
中,有一个MainProc()
,它使用
CustomProcHandler = (WNDPROC)SetWindowLong(hwndButton, GWL_WNDPROC, (long)CustomProc)
主要条款h:
#include <windows.h>
#include <iostream>
using namespace std;
const char g_szClassName[] = "Applicaton";
static HWND hwnd, hwndButton;
static HINSTANCE hInst;
static WNDPROC buttonProcHandler;
LRESULT CALLBACK MainProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK ButtonProc(HWND, UINT, WPARAM, LPARAM);
custom.cpp:
#include "main.h"
LRESULT CALLBACK ButtonProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){
switch(msg){
case WM_CREATE:
break;
case WM_MOUSEMOVE:
break;
case WM_LBUTTONDOWN:
break;
default:
return CallWindowProc(buttonProcHandler, hwnd, msg, wParam, lParam);
}
return 0;
}
问题是按钮消失了。。。但是当我在main.cpp
中移动buttonProc()
时,一切都正常
所以,我猜我在声明全局变量时出错了,比如静态WNDPROC buttonProcHandler
我知道我所做的是完全错误的,而且还有更好的方法。我只是不知道那是什么
有人能帮我/教我创建自定义过程的标准方法吗?你对
静态的工作原理有一个基本的误解。由于将main.h
包含在单独的.cpp
文件中,因此每个.cpp
都会获得main.h
声明的静态
变量的本地副本。如果您希望多个.cpp
文件彼此共享全局变量,请不要在共享的.h
文件中将它们声明为静态
,在单个.cpp
文件中定义一次,然后在共享的.h
文件中使用外部
声明。此外,当您开始对多个按钮进行子类化时,每个按钮都需要单独的WNDPROC
变量,因为您必须将之前的WNDPROC
正确地分配到CallWindowProc()
,因此不能对所有按钮使用单个WNDPROC
变量。处理此问题的最佳方法是将每个按钮包装在一个类中,该类处理它所持有的单个按钮的子类。您应该使用SetWindowLongPtr
和(LONG_PTR)ButtonProc
,否则指针值可能会被剪切。太棒了,它工作起来很有魅力!谢谢你,雷米·勒博先生@VTT:除非你下定决心支持Win9x和Windows 2000,否则你不应该这样做。控件子类化的正确方法是调用SetWindowSubclass
,如中所述。
#include "main.h"
LRESULT CALLBACK ButtonProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){
switch(msg){
case WM_CREATE:
break;
case WM_MOUSEMOVE:
break;
case WM_LBUTTONDOWN:
break;
default:
return CallWindowProc(buttonProcHandler, hwnd, msg, wParam, lParam);
}
return 0;
}