最近脑抽,用win32 API写了一个数据处理平台,将各个窗口定义为Class进行自管理,但是由于类常规成员函数不能作为窗口函数,只能将窗口函数定义为静态函数,这样写则后续在窗口函数中引用的函数都要定义为静态函数,且不能引用类中的成员变量,非常麻烦,通过调研(竟然在20年前的贴子中找到了一个方法,但只是思路,无法直接使用)可以在createstruct中将成员函数传递给窗口,实现如下,包含一个窗口及对话框。
//GLOBALWINPROC.H
#pragma once
//这是全局窗口函数,及窗口基类
#include "stdafx.h"
#ifndef GLOBAL_WIN_PROC_H
#define GLOBAL_WIN_PROC_H
//基类
class CLASSWINPROC {
public:
virtual LRESULT WINAPI WinProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) = 0;
~CLASSWINPROC() {};
};
//窗口函数
LRESULT WINAPI GlobalWinProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
//对话框函数
LRESULT WINAPI GlobalDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
#endif // !GLOBAL_WIN_PROC_H
#pragma once
#include "stdafx.h"
LRESULT WINAPI GlobalWinProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
CLASSWINPROC *pclass = NULL;
//在第一个消息到来时,设置userdata,使在后续消息中能调用自定义窗口函数
//第一个消息为WM_NCCREATE,这里也把wm_crete写上,更好理解一些
if (message == WM_CREATE|| message == WM_NCCREATE) {
CREATESTRUCT** cs = (CREATESTRUCT **)lParam;
pclass = (CLASSWINPROC*)((*cs)->lpCreateParams);
SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(pclass));
return pclass->WinProc(hWnd, message, wParam, lParam);
}
if (message == WM_DESTROY|| message == WM_CLOSE) {//当收到关闭窗口消息时,将窗口函数设置为默认窗口函数
LONG_PTR user_data = GetWindowLongPtr(hWnd, GWLP_USERDATA);
delete reinterpret_cast<CLASSWINPROC *>(user_data);//删除在构造函数的创建的对象
SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)DefWindowProc);
return DefWindowProc(hWnd, message, wParam, lParam);
}
else {//下面的消息均调用自定义窗口函数
LONG_PTR user_data = GetWindowLongPtr(hWnd, GWLP_USERDATA);
pclass = reinterpret_cast<CLASSWINPROC *>(user_data);
return pclass->WinProc(hWnd, message, wParam, lParam);
}
//return 0;
}
LRESULT WINAPI GlobalDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
CLASSWINPROC *pclass ;
if (message == WM_INITDIALOG) {
//对话框的第一个消息并不是WM_INITDIALO,只有在此消息到来时才设置userdata
pclass = (CLASSWINPROC*)(lParam);
SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)(pclass));
return pclass->WinProc(hWnd, message, wParam, lParam);
}
LONG_PTR user_data = GetWindowLongPtr(hWnd, GWLP_USERDATA);
if(user_data!=NULL)//未设置userdata时,返回的值为NULL
return ((CLASSWINPROC*)user_data)->WinProc(hWnd, message, wParam, lParam);
return 0;
}
class SEISMICVIEW:CLASSWINPROC {
public:
SEISMICVIEW(){};
SEISMICVIEW(HWND hwnd, HINSTANCE hinst, const RECT rct, TCHAR* szWindowClass) :hParentWnd(hwnd), hInst(hinst){
//
SEISMICVIEW *sv = new SEISMICVIEW(*this);//这个对象一直保留直到窗口关闭
CREATESTRUCT cs;
cs.lpCreateParams = sv;
seismicview = CreateWindow(szWindowClass, _T("childwindow"), WS_CHILD | WS_VISIBLE | WS_CAPTION,
0, 0, rct.right, rct.bottom, hParentWnd, nullptr, hInst, &cs);
sv->seismicview = seismicview;
int n = GetLastError();
if (seismicview == NULL) {
delete sv;
}
}
~SEISMICVIEW() { };
public:
HWND seismicview ;//
HWND hParentWnd;
HINSTANCE hInst;
//message handle
LRESULT WINAPI WinProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
};
class TRACEHEADVIEW:CLASSWINPROC {
public:
TRACEHEADVIEW(HWND hWnd, HINSTANCE hInst, SEISMICPLOT* sp) : hParentWnd(hWnd), hInst(hInst), sp(sp) {
DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_DIALOGTRACEHEAD),hParentWnd, (DLGPROC)GlobalDlgProc,(LPARAM)this);
}
LRESULT WINAPI WinProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
public:
HWND hParentWnd;
HINSTANCE hInst;
HWND hWnddlg;
};