如何在回调函数中使用非静态变量
怎么在回调函数中使用非静态变量
我自己写了一个窗口类。(源码见下)
首先是我在回调函数MyWndPro()中都要用到成员变量m_mousepoint,但MyWndPro()是静态函数提示“Error:非静态成员必须与特定对象相对”,怎么在静态函数中使用非静态变量呢?
因此我就想要获取窗口指针,用来调用特定对象的成员。但使用以下两种方法都失败了,不知还有什么好方法?
BOOL MyWindow::Create(LPCWSTR lpszCaption, const RECT& rect, HWND hParentWnd, UINT nID)
{ ...
SetWindowLong(m_hWnd, GWL_USERDATA, (LONG)this); //第一种方法
SetWindowLongPtr(m_hWnd, GWL_USERDATA, (LONG)(LONG_PTR)this); //第二种方法
}
LRESULT CALLBACK MyWindow::MyWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{ ...
MyWindow *_this = (MyWindow *)GetWindowLong(hWnd, GWL_USERDATA); //第一种方法
LONG_PTR plptrWin = GetWindowLongPtr(hWnd, GWLP_USERDATA); //第二种方法
}
头文件如下
///////////////////////
///////MyWnd.h
///////////////
#pragma once
#include<Windows.h>
class MyWindow
{
public:
MyWindow(void);
MyWindow(HINSTANCE);
~MyWindow(void);
private:
MyWindow(const MyWindow &OtherMyWindow);
MyWindow &operator=(const MyWindow &OtherMyWindow);
public:
BOOL Create(LPCWSTR lpszCaption, const RECT& rect, HWND hParentWnd, UINT nID);
private:
static LRESULT CALLBACK MyWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
public:
HINSTANCE m_hInstance;
HWND m_hWnd;
HWND m_hParentWnd;
TCHAR WndName[100];
POINT m_mousepoint;
};
//////////////////////
///////MyWnd.cpp
/////////////////////
#include<Windows.h>
#include"testwindow.h"
#include <tchar.h>
MyWindow::MyWindow(void) :m_hWnd(NULL), m_hParentWnd(NULL)
{
m_mousepoint = {0,0};
}
MyWindow::MyWindow(HINSTANCE hInstance) : m_hWnd(NULL), m_hParentWnd(NULL)
{
m_hInstance = hInstance;
m_mousepoint = {0,0};
}
MyWindow::~MyWindow(void)
{
}
BOOL MyWindow::Create(LPCWSTR lpszCaption, const RECT& rect, HWND hParentWnd, UINT nID)
{
if (m_hWnd)
{
return FALSE;
}
WNDCLASSEX wcex;
HBRUSH bgBrush = CreateSolidBrush(RGB(255, 255, 255));
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = MyWndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = m_hInstance;
wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = bgBrush;
wcex.lpszMenuName = NULL;
wcex.lpszClassName = L"MyWindow";
wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
RegisterClassEx(&wcex);
m_hParentWnd = hParentWnd;
m_hWnd = CreateWindowEx(WS_EX_LAYERED | WS_EX_TOOLWINDOW, L"MyWindow", lpszCaption, WS_SIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT, 500, 500, HWND_DESKTOP, NULL, m_hInstance, NULL);
if (NULL == m_hWnd)
{
return FALSE;
}
SetWindowLong(m_hWnd, GWL_USERDATA, (LONG)this);
//SetWindowLongPtr(m_hWnd, GWL_USERDATA, (LONG)(LONG_PTR)this);
ShowWindow(m_hWnd, SW_SHOW);
UpdateWindow(m_hWnd);
return TRUE;
}
LRESULT CALLBACK MyWindow::MyWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
MyWindow *_this = (MyWindow *)GetWindowLong(hWnd, GWL_USERDATA);
if (_this == NULL)
{
return DefWindowProc(hWnd, message, wParam, lParam);
}
_this->m_hWnd = hWnd;
/*
LONG_PTR plptrWin = GetWindowLongPtr(hWnd, GWLP_USERDATA);
if (plptrWin == NULL)
{
return DefWindowProc(hWnd, message, wParam, lParam);
}
MyWindow* pWin = reinterpret_cast<MyWindow*>(plptrWin);
*/
switch (message)
{
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
break;
case WM_ERASEBKGND:
return TRUE;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
------解决思路----------------------
SetProp
The SetProp function adds a new entry or changes an existing entry in the property list of the specified window. The function adds a new entry to the list if the specified character string does not exist already in the list. The new entry contains the string and the handle. Otherwise, the function replaces the string's current handle with the specified handle.
BOOL SetProp(
HWND hWnd, // handle of window
LPCTSTR lpString, // atom or address of string
HANDLE hData // handle of data
);
和
GetProp
The GetProp function retrieves a data handle from the property list of the given window. The given character string identifies the handle to be retrieved. The string and handle must have been added to the property list by a previous call to the SetProp function.
HANDLE GetProp(
HWND hWnd, // handle of window
LPCTSTR lpString // atom or address of string
);
如:
WNDPROC oldProc=0;
LRESULT CALLBACK newMenuProc(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam)
{
// afxDump << Msg << "\r\n";
switch(Msg)
{
case 0x01EE://MN_MOUSEMOVE: not comes !
// afxDump << Msg << "\r\n";
break;
// only inside menu
case 0x01ED://MN_BUTTONDOWN://
// afxDump << Msg << "\r\n";
break;
case 0x01EF://MN_BUTTONUP://
// afxDump << Msg << "\r\n";
break;
//
case WM_DESTROY:
case WM_NCDESTROY:
oldProc=0;
break;
}
return CallWindowProc((WNDPROC)::GetProp(hWnd,"MyMenuProc"),hWnd,Msg,wParam,lParam);
}
------解决思路----------------------
看来这个参数不能这样设置,应该这样做:
BOOL CxWinBase::Create( LPCTSTR lpszWindowName,const RECT& rect,HINSTANCE hHandle)
{
m_hWnd= CreateWindow(
DEFAUL_WINCLASS_NAME,
lpszWindowName,
WS_OVERLAPPEDWINDOW,
rect.left,rect.top,rect.right-rect.left,rect.bottom-rect.top,
NULL, NULL,hHandle,this);
return (m_hWnd !=NULL);
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
// Get a pointer to the window class object.
CWinXXX* pWin = (CxWinBase*) GetWindowLong(hWnd, GWL_USERDATA);
switch (message)
{
case WM_INITDIALOG:
case WM_NCCREATE:
pWin = (CWinXXX *) ((CREATESTRUCT *)lParam)->lpCreateParams;
.............
我自己写了一个窗口类。(源码见下)
首先是我在回调函数MyWndPro()中都要用到成员变量m_mousepoint,但MyWndPro()是静态函数提示“Error:非静态成员必须与特定对象相对”,怎么在静态函数中使用非静态变量呢?
因此我就想要获取窗口指针,用来调用特定对象的成员。但使用以下两种方法都失败了,不知还有什么好方法?
BOOL MyWindow::Create(LPCWSTR lpszCaption, const RECT& rect, HWND hParentWnd, UINT nID)
{ ...
SetWindowLong(m_hWnd, GWL_USERDATA, (LONG)this); //第一种方法
SetWindowLongPtr(m_hWnd, GWL_USERDATA, (LONG)(LONG_PTR)this); //第二种方法
}
LRESULT CALLBACK MyWindow::MyWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{ ...
MyWindow *_this = (MyWindow *)GetWindowLong(hWnd, GWL_USERDATA); //第一种方法
LONG_PTR plptrWin = GetWindowLongPtr(hWnd, GWLP_USERDATA); //第二种方法
}
头文件如下
///////////////////////
///////MyWnd.h
///////////////
#pragma once
#include<Windows.h>
class MyWindow
{
public:
MyWindow(void);
MyWindow(HINSTANCE);
~MyWindow(void);
private:
MyWindow(const MyWindow &OtherMyWindow);
MyWindow &operator=(const MyWindow &OtherMyWindow);
public:
BOOL Create(LPCWSTR lpszCaption, const RECT& rect, HWND hParentWnd, UINT nID);
private:
static LRESULT CALLBACK MyWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
public:
HINSTANCE m_hInstance;
HWND m_hWnd;
HWND m_hParentWnd;
TCHAR WndName[100];
POINT m_mousepoint;
};
//////////////////////
///////MyWnd.cpp
/////////////////////
#include<Windows.h>
#include"testwindow.h"
#include <tchar.h>
MyWindow::MyWindow(void) :m_hWnd(NULL), m_hParentWnd(NULL)
{
m_mousepoint = {0,0};
}
MyWindow::MyWindow(HINSTANCE hInstance) : m_hWnd(NULL), m_hParentWnd(NULL)
{
m_hInstance = hInstance;
m_mousepoint = {0,0};
}
MyWindow::~MyWindow(void)
{
}
BOOL MyWindow::Create(LPCWSTR lpszCaption, const RECT& rect, HWND hParentWnd, UINT nID)
{
if (m_hWnd)
{
return FALSE;
}
WNDCLASSEX wcex;
HBRUSH bgBrush = CreateSolidBrush(RGB(255, 255, 255));
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = MyWndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = m_hInstance;
wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = bgBrush;
wcex.lpszMenuName = NULL;
wcex.lpszClassName = L"MyWindow";
wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
RegisterClassEx(&wcex);
m_hParentWnd = hParentWnd;
m_hWnd = CreateWindowEx(WS_EX_LAYERED | WS_EX_TOOLWINDOW, L"MyWindow", lpszCaption, WS_SIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT, 500, 500, HWND_DESKTOP, NULL, m_hInstance, NULL);
if (NULL == m_hWnd)
{
return FALSE;
}
SetWindowLong(m_hWnd, GWL_USERDATA, (LONG)this);
//SetWindowLongPtr(m_hWnd, GWL_USERDATA, (LONG)(LONG_PTR)this);
ShowWindow(m_hWnd, SW_SHOW);
UpdateWindow(m_hWnd);
return TRUE;
}
LRESULT CALLBACK MyWindow::MyWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
MyWindow *_this = (MyWindow *)GetWindowLong(hWnd, GWL_USERDATA);
if (_this == NULL)
{
return DefWindowProc(hWnd, message, wParam, lParam);
}
_this->m_hWnd = hWnd;
/*
LONG_PTR plptrWin = GetWindowLongPtr(hWnd, GWLP_USERDATA);
if (plptrWin == NULL)
{
return DefWindowProc(hWnd, message, wParam, lParam);
}
MyWindow* pWin = reinterpret_cast<MyWindow*>(plptrWin);
*/
switch (message)
{
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
break;
case WM_ERASEBKGND:
return TRUE;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
------解决思路----------------------
SetProp
The SetProp function adds a new entry or changes an existing entry in the property list of the specified window. The function adds a new entry to the list if the specified character string does not exist already in the list. The new entry contains the string and the handle. Otherwise, the function replaces the string's current handle with the specified handle.
BOOL SetProp(
HWND hWnd, // handle of window
LPCTSTR lpString, // atom or address of string
HANDLE hData // handle of data
);
和
GetProp
The GetProp function retrieves a data handle from the property list of the given window. The given character string identifies the handle to be retrieved. The string and handle must have been added to the property list by a previous call to the SetProp function.
HANDLE GetProp(
HWND hWnd, // handle of window
LPCTSTR lpString // atom or address of string
);
如:
WNDPROC oldProc=0;
LRESULT CALLBACK newMenuProc(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam)
{
// afxDump << Msg << "\r\n";
switch(Msg)
{
case 0x01EE://MN_MOUSEMOVE: not comes !
// afxDump << Msg << "\r\n";
break;
// only inside menu
case 0x01ED://MN_BUTTONDOWN://
// afxDump << Msg << "\r\n";
break;
case 0x01EF://MN_BUTTONUP://
// afxDump << Msg << "\r\n";
break;
//
case WM_DESTROY:
case WM_NCDESTROY:
oldProc=0;
break;
}
return CallWindowProc((WNDPROC)::GetProp(hWnd,"MyMenuProc"),hWnd,Msg,wParam,lParam);
}
------解决思路----------------------
看来这个参数不能这样设置,应该这样做:
BOOL CxWinBase::Create( LPCTSTR lpszWindowName,const RECT& rect,HINSTANCE hHandle)
{
m_hWnd= CreateWindow(
DEFAUL_WINCLASS_NAME,
lpszWindowName,
WS_OVERLAPPEDWINDOW,
rect.left,rect.top,rect.right-rect.left,rect.bottom-rect.top,
NULL, NULL,hHandle,this);
return (m_hWnd !=NULL);
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
// Get a pointer to the window class object.
CWinXXX* pWin = (CxWinBase*) GetWindowLong(hWnd, GWL_USERDATA);
switch (message)
{
case WM_INITDIALOG:
case WM_NCCREATE:
pWin = (CWinXXX *) ((CREATESTRUCT *)lParam)->lpCreateParams;
.............