窗口类 [英] Window class

查看:70
本文介绍了窗口类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个包含

实例化窗口并显示它的所有功能的类。我有一个SetWindowLong /

GetWindowLong对成功地将''this''指针存储在hWnd'的
GWL_USERDATA中,但指针就是'似乎总是指向基类的
而不是派生类。我不知道我在做什么

错了,这让我疯了几个小时。因此,静态

WndProc处理函数永远不会将消息路由到类的实际

wndproc(它是虚拟的并在派生类中实现) - 它给出了

我的''纯虚函数调用''的一些低级调试错误....为什么不能

我能看到派生类吗?帮助!....

谢谢


这是在window1.h(基类)


#ifndef WINDOW1CLASS_DEFINED


#define WINDOW1CLASS_DEFINED


class Window1


{


public:


//变量:


HWND hWnd;


HCURSOR hcWait,hcArrow;


BOOL bWaiting;

//方法:


void创建(HINSTANCE hInst,


HICON hIcon,


HICON hIconSm,


HBRUSH hbrBackground,

LPCTSTR lpszCaption,

int nClassStyle,


int nWindowStyle);

静态LRESULT CALLBACK WPHandler(



UINT uMsg,


WPARAM wParam,

LPARAM lParam);


虚拟LRESULT WndProc(HWND hWnd,


UINT uMsg,


WPARAM wParam,


LPARAM lPara m)= 0;


virtual int ShowModally(int nCmdShow)= 0;


//构造函数/析构函数:


Window1():hWnd(NULL){};


virtual~Window1(){};


Window1(HINSTANCE hInst,


HICON hIcon,


HICON hIconSm,


HBRUSH hbrBackground,


LPCTSTR lpszCaption,

int nClassStyle,

int nWindowStyle);


};


#endif


//这是在Window1.cpp中


// ======================================


#include" Generics.h"


#include" Window1.h"


Window1: :Window1(HINSTANCE hInst,


HICON hIcon,


HICON hIconSm,


HBRUSH hbrBackground ,


LPCTSTR lpszCaption,

int nClassStyle,

int nWindowStyle)


{

创建(hInst,hIcon,hIconSm,hbrBackground,

lpszCaption,nClassStyle,nWindowStyle);


}


LRESULT CALLBACK Window1 :: WPHandler(HWND hWnd,


UINT uMsg,


WPARAM wParam ,


LPARAM lParam)


{


if(uMsg == WM_NCCREATE)


{


LPCREATESTRUCT lpcs =(LPCREATESTRUCT)lParam;


SetWindowLong(hWnd,GWL_USERDATA,( long)lpcs-> lpCreateParams);


}


Window1 * pThis =(Window1 *)(LPVOID)(:: GetWindowLong( hWnd,GWL_USERDATA));


// Window1 * pThis =(Window1 *)(GetWindowLong(hWnd,GWL_USERDATA));


if (pThis)返回pThis-> WndProc(hWnd,uMsg,wParam,lParam);


else返回DefWindowProc(hWnd,uMsg,wParam,lParam);


}


void Window1 ::创建(HINSTANCE hInst,


HICON hIcon,

HICON hIconSm,


HBRUSH hbrBackground,


LPCTSTR lpszCaption,

int nClassStyle,


int nWindowStyle)


{


bWaiting = FALSE;


WNDCLASSEX wcx;


memset(& wcx,0,sizeof(WNDCLASSEX));


wcx.cbSize = sizeof (WNDCLASSEX);


wcx.style = nClassStyle;


wcx.lpfnWndProc = Window1 :: WPHandler;

wcx.hInstance = hInst;


wcx.hIcon = NULL;


wcx.hCursor = NULL;


wcx.hbrBackground = hbrBackground;


wcx.lpszMenuName = NULL;


wcx.lpszClassName = lpszCaption ;


wcx.hIconSm = NULL;


hcWait =(HCURSOR)LoadImage(NULL,


IDC_ARROW,


IMAGE_CURSOR,


CW_USEDEFAULT,


CW_USEDEFAULT,


LR_DEFAULTSIZE | LR_DEFAULTCOLOR | LR_SHARED);


hcArrow =(HCURSOR)LoadImage(NULL,


IDC_WAIT,


IMAGE_CURSOR,


CW_USEDEFAULT,


CW_USEDEFAULT,


LR_DEFAULTSIZE | LR_DEFAULTCOLOR | LR_SHARED);


ATOM ClassName = RegisterClassEx(& wcx);


hWnd = CreateWindow((LPCTSTR)ClassName,


lpszCaption,

nWindowStyle,

CW_USEDEFAULT,


CW_USEDEFAULT,


CW_USEDEFAULT,


CW_USEDEFAULT,


(HWND)NULL,

(HMENU)NULL,


(HINSTANCE)hInst,


(LPVOID)this);
< br $>
}


//基类定义如此(settingsdlg.h)


#include" Window1.h"


class SettingsDlg:public Window1


{


public:


//构造函数/析构函数:


SettingsDlg(HINSTANCE hInst,


HICON hIcon,


HICON hIconSm,


HBRUSH hbrBackground,

LPCTSTR lpszCaption,

int nClassStyle,


int nWindowStyle):


Window1(hInst,


hIcon,


hIconSm,


hbrBackground,

lpszCaption,

nClassStyle,


nWindowStyle){};


// SettingsDlg(){};


// ~SettingsDlg(){};

LRESULT WndProc(HWND hWnd,


UINT uMsg,


WPARAM wParam,

LPARAM lParam);


int ShowModally(int nCmdShow);


};


//(settingsdlg.cpp)


#include" Generics.h"


#include" settingsdlg.h" ;


int SettingsDlg :: ShowModally(int nCmdShow)


{


{


if(hWnd)


{


ShowWindow(hWnd,nCmdShow);


UpdateWindow(hWnd);


}


其他


返回-1;


}

{


MSG msg;

while(GetMessage(& msg,hWnd,0,0))


{


TranslateMessage(& msg) );


DispatchMessage(& msg);


}


return(int) msg.wParam;


}


}



LRESULT SettingsDlg :: WndProc(HWND hWnd,


UINT uMsg,


WPARAM wParam,


LPARAM lParam)


{


开关(uMsg)


{


案例WM_MOUSEMOVE:


{


SetCursor((bWaiting)? (hcWait):( hcArrow));


返回0;


}


/ *


案例WM_CLOSE:


{


PostMessage(hWnd,WM_QUIT,0,0) );


返回0;


}


* /


}


返回DefWindowProc(hWnd,uMsg,wParam,lParam);


}


//我的winmain cpp文件如下所示:


#include" Generics.h"


#包括SettingsDlg.h


int WINAPI WinMain(HINSTANCE hInstance,


HINSTANCE hPrevInstance,


LPSTR lpszCmdLine,

int nCmdShow





{


HICON hIcon =(HICON)LoadImage(hInstance,


MAKEINTRESOURCE(IDI_TRANS),


IMAGE_ICON,


GetSystemMetrics(SM_CXICON),

GetSystemMetrics(SM_CYICON),


LR_ DEFAULTCOLOR | LR_SHARED),


hIconSm =(HICON)LoadImage(hInstance,


MAKEINTRESOURCE(IDI_TRANS),


IMAGE_ICON,


GetSystemMetrics(SM_CXSMICON),

GetSystemMetrics(SM_CYSMICON),


LR_DEFAULTCOLOR | LR_SHARED);

SettingsDlg sdlg(hInstance,


hIcon,


hIconSm,

(HBRUSH)(COLOR_3DFACE + 1),

SpaceMaze设置,


CS_OWNDC | CS_HREDRAW | CS_VREDRAW,


WS_OVERLAPPEDWINDOW);


返回sdlg.ShowModally(SW_SHOWMAXIMIZED);


}



非常感谢任何可以帮助我摆脱困境的人!


i''m trying to create a class that will contain all the features of
instantiating a window and showing it. I''ve got the SetWindowLong /
GetWindowLong pair to succesfully store the ''this'' pointer in the hWnd''s
GWL_USERDATA, but the pointer that it''s referring to always seems to point
to the base class and never the derived class. I don''t know what I''m doing
wrong, this has been driving me mad for hours. Consequently, the static
WndProc handler function can never route the messages to the class''s actual
wndproc (which is virtual and implemented in the derived class) - it gives
me some low-level debug error of ''pure virtual function call'' .... WHY can''t
I get it to see the derived class? help!....
Thanks

this is in window1.h (the base class)

#ifndef WINDOW1CLASS_DEFINED

#define WINDOW1CLASS_DEFINED

class Window1

{

public:

//variables:

HWND hWnd;

HCURSOR hcWait, hcArrow;

BOOL bWaiting;
//methods:

void Create( HINSTANCE hInst,

HICON hIcon,

HICON hIconSm,

HBRUSH hbrBackground,

LPCTSTR lpszCaption,

int nClassStyle,

int nWindowStyle);

static LRESULT CALLBACK WPHandler(

HWND hWnd,

UINT uMsg,

WPARAM wParam,

LPARAM lParam);

virtual LRESULT WndProc(HWND hWnd,

UINT uMsg,

WPARAM wParam,

LPARAM lParam) = 0;

virtual int ShowModally(int nCmdShow) = 0;

//constructor/destructor:

Window1() : hWnd(NULL) {};

virtual ~Window1() {};

Window1( HINSTANCE hInst,

HICON hIcon,

HICON hIconSm,

HBRUSH hbrBackground,

LPCTSTR lpszCaption,

int nClassStyle,

int nWindowStyle);

};

#endif

//this is in Window1.cpp

//======================================

#include "Generics.h"

#include "Window1.h"

Window1::Window1( HINSTANCE hInst,

HICON hIcon,

HICON hIconSm,

HBRUSH hbrBackground,

LPCTSTR lpszCaption,

int nClassStyle,

int nWindowStyle)

{

Create(hInst, hIcon, hIconSm, hbrBackground,

lpszCaption, nClassStyle, nWindowStyle);

}

LRESULT CALLBACK Window1::WPHandler( HWND hWnd,

UINT uMsg,

WPARAM wParam,

LPARAM lParam)

{

if(uMsg == WM_NCCREATE)

{

LPCREATESTRUCT lpcs = (LPCREATESTRUCT)lParam;

SetWindowLong(hWnd, GWL_USERDATA, (long)lpcs->lpCreateParams);

}

Window1* pThis = (Window1*)(LPVOID)(::GetWindowLong(hWnd, GWL_USERDATA));

//Window1* pThis = (Window1*)(GetWindowLong(hWnd, GWL_USERDATA));

if(pThis) return pThis->WndProc(hWnd, uMsg, wParam, lParam);

else return DefWindowProc(hWnd, uMsg, wParam, lParam);

}

void Window1::Create(HINSTANCE hInst,

HICON hIcon,

HICON hIconSm,

HBRUSH hbrBackground,

LPCTSTR lpszCaption,

int nClassStyle,

int nWindowStyle)

{

bWaiting = FALSE;

WNDCLASSEX wcx;

memset(&wcx, 0, sizeof(WNDCLASSEX));

wcx.cbSize = sizeof(WNDCLASSEX);

wcx.style = nClassStyle;

wcx.lpfnWndProc = Window1::WPHandler;

wcx.hInstance = hInst;

wcx.hIcon = NULL;

wcx.hCursor = NULL;

wcx.hbrBackground = hbrBackground;

wcx.lpszMenuName = NULL;

wcx.lpszClassName = lpszCaption;

wcx.hIconSm = NULL;

hcWait = (HCURSOR)LoadImage( NULL,

IDC_ARROW,

IMAGE_CURSOR,

CW_USEDEFAULT,

CW_USEDEFAULT,

LR_DEFAULTSIZE | LR_DEFAULTCOLOR | LR_SHARED);

hcArrow = (HCURSOR)LoadImage( NULL,

IDC_WAIT,

IMAGE_CURSOR,

CW_USEDEFAULT,

CW_USEDEFAULT,

LR_DEFAULTSIZE | LR_DEFAULTCOLOR | LR_SHARED);

ATOM ClassName = RegisterClassEx(&wcx);

hWnd = CreateWindow( (LPCTSTR)ClassName,

lpszCaption,

nWindowStyle,

CW_USEDEFAULT,

CW_USEDEFAULT,

CW_USEDEFAULT,

CW_USEDEFAULT,

(HWND)NULL,

(HMENU)NULL,

(HINSTANCE)hInst,

(LPVOID)this);

}


//and the base class is defined as such (settingsdlg.h)

#include "Window1.h"

class SettingsDlg : public Window1

{

public:

//constructor/destructor:

SettingsDlg( HINSTANCE hInst,

HICON hIcon,

HICON hIconSm,

HBRUSH hbrBackground,

LPCTSTR lpszCaption,

int nClassStyle,

int nWindowStyle) :

Window1( hInst,

hIcon,

hIconSm,

hbrBackground,

lpszCaption,

nClassStyle,

nWindowStyle) {};

//SettingsDlg() {};

//~SettingsDlg() {};
LRESULT WndProc(HWND hWnd,

UINT uMsg,

WPARAM wParam,

LPARAM lParam);

int ShowModally(int nCmdShow);

};

//(settingsdlg.cpp)

#include "Generics.h"

#include "settingsdlg.h"

int SettingsDlg::ShowModally(int nCmdShow)

{

{

if(hWnd)

{

ShowWindow(hWnd, nCmdShow);

UpdateWindow(hWnd);

}

else

return -1;

}
{

MSG msg;

while(GetMessage(&msg, hWnd, 0, 0))

{

TranslateMessage(&msg);

DispatchMessage(&msg);

}

return (int)msg.wParam;

}

}



LRESULT SettingsDlg::WndProc( HWND hWnd,

UINT uMsg,

WPARAM wParam,

LPARAM lParam)

{

switch(uMsg)

{

case WM_MOUSEMOVE:

{

SetCursor((bWaiting) ? (hcWait) : (hcArrow));

return 0;

}

/*

case WM_CLOSE:

{

PostMessage(hWnd, WM_QUIT, 0, 0);

return 0;

}

*/

}

return DefWindowProc(hWnd, uMsg, wParam, lParam);

}

//and my winmain cpp file looks like this:

#include "Generics.h"

#include "SettingsDlg.h"

int WINAPI WinMain( HINSTANCE hInstance,

HINSTANCE hPrevInstance,

LPSTR lpszCmdLine,

int nCmdShow

)

{

HICON hIcon = (HICON)LoadImage( hInstance,

MAKEINTRESOURCE(IDI_TRANS),

IMAGE_ICON,

GetSystemMetrics(SM_CXICON),

GetSystemMetrics(SM_CYICON),

LR_DEFAULTCOLOR | LR_SHARED),

hIconSm = (HICON)LoadImage( hInstance,

MAKEINTRESOURCE(IDI_TRANS),

IMAGE_ICON,

GetSystemMetrics(SM_CXSMICON),

GetSystemMetrics(SM_CYSMICON),

LR_DEFAULTCOLOR | LR_SHARED);
SettingsDlg sdlg( hInstance,

hIcon,

hIconSm,

(HBRUSH)(COLOR_3DFACE + 1),

"SpaceMaze settings",

CS_OWNDC | CS_HREDRAW | CS_VREDRAW,

WS_OVERLAPPEDWINDOW);

return sdlg.ShowModally(SW_SHOWMAXIMIZED);

}



Thanks ever so much to anybody that can help me out of this !


推荐答案

在执行Window1构造函数时,调用构造函数时创建的对象仍然是Window1

对象。这就是C ++对象如何创建的工作原理 - 调用虚拟函数(或函数具有虚拟和/或
语义,即类似于你的'')。如果你希望你的类被子类化,那么构造函数(或析构函数)是没有意义的。


但是你还是有一个C ++类。保留HWND字典 - > Window1

类,并让你的窗口程序使用该字典查找特定消息的

Window1对象。


Volker


" Bonj" < a@b.com>在消息中写道

news:uO **************** @ TK2MSFTNGP09.phx.gbl ...
The object you create when calling the constructor is still a "Window1"
object when the Window1 constructor is executed. That''s how C++ object
creation works - calling virtual functions (or functions with a "virtual"
semantic, ie. like your''s) in the constructor (or the destructor) is
pointless if you expect your class to be subclassed.

But then you have a C++ class anyway. Keep a dictionary of HWND -> Window1
class, and have your window procedure use that dictionary to find the
Window1 object for a certain message.

Volker

"Bonj" <a@b.com> wrote in message
news:uO****************@TK2MSFTNGP09.phx.gbl...
i''我试图创建一个类,它将包含实例化窗口并显示它的所有功能。我已经有了SetWindowLong /
GetWindowLong对来成功地将''this'指针存储在hWnd'的GWL_USERDATA中,但它所指的指针总是似乎是
指向基类,而不是派生类。我不知道我做错了什么,这让我疯了几个小时。因此,静态的WndProc处理函数永远不会将消息路由到类的
实际的wndproc(它是虚拟的并在派生类中实现) - 它
给了我一些低 - 纯虚函数调用的级别调试错误....为什么
我不能看到派生类?帮助!....
谢谢
i''m trying to create a class that will contain all the features of
instantiating a window and showing it. I''ve got the SetWindowLong /
GetWindowLong pair to succesfully store the ''this'' pointer in the hWnd''s
GWL_USERDATA, but the pointer that it''s referring to always seems to point to the base class and never the derived class. I don''t know what I''m doing wrong, this has been driving me mad for hours. Consequently, the static
WndProc handler function can never route the messages to the class''s actual wndproc (which is virtual and implemented in the derived class) - it gives me some low-level debug error of ''pure virtual function call'' .... WHY can''t I get it to see the derived class? help!....
Thanks



但它并没有尝试从
构造函数,它试图从WndProcHandler这样做,这是基类的静态

方法。

它真的不是真正意义上的''子类'',我认为

它在某种程度上但我认为子类化涉及用另一个替换一个WndProc $ / b $ b以便处理额外的消息,这只是一个中心

WndProc将消息路由到派生类实例化。

我不知道你的意思''保留字典''。但是我已经有了它的工作现在是b $ b,这是主要的事情 - 我只是好奇我想为什么在实际上调用

派生类成员函数WM_CREATE消息(当

指向其内存地址的指针此时已知,尽管只是公正)

导致它在''无效的v-table'上崩溃什么东西,但是当它被忘记并再次检索时,将它调用

下一条消息,

工作正常.....

再次感谢

" Volker Hilsheimer" < VO ** @ trolltech.com>在留言中写道

新闻:uw **************** @ tk2msftngp13.phx.gbl ...
But it wasn''t trying to call a member function of the derived class from the
constructor, it was trying to do so from WndProcHandler, which is a static
method of the base class.
It isn''t really being ''subclassed'' in the true sense of the word, I suppose
it is in a way but I thought subclassing involved replacing a WndProc with
another one in order to handle extra messages, this is just one central
WndProc routing the messages to the derived class instantiations.
I don''t know what you mean by ''keep a dictionary''. But I''ve got it working
now, which is the main thing - I was just curious I guess as to why calling
the derived class member function on the actual WM_CREATE message (when the
pointer to its memory address is at this time known, albeit only just)
causes it to crash on an ''invalid v-table'' or something, but calling it on
the next message when the pointer has been forgotten and retrieved again,
works fine.....
Thanks again
"Volker Hilsheimer" <vo**@trolltech.com> wrote in message
news:uw****************@tk2msftngp13.phx.gbl...
你的对象当执行Window1构造函数时,在调用构造函数时仍然是Window1对象时创建。这就是C ++对象创建的工作方式 - 在构造函数(或析构函数)中调用虚函数(或带有虚拟语义的函数,即类似于你的')如果你希望你的类被子类化,那么毫无意义。

但是你还是有一个C ++类。保留HWND字典 - > Window1
类,并让你的窗口程序使用该字典来查找特定消息的Window1对象。

Volker

Bonj < a@b.com>在消息中写道
新闻:uO **************** @ TK2MSFTNGP09.phx.gbl ...
The object you create when calling the constructor is still a "Window1"
object when the Window1 constructor is executed. That''s how C++ object
creation works - calling virtual functions (or functions with a "virtual"
semantic, ie. like your''s) in the constructor (or the destructor) is
pointless if you expect your class to be subclassed.

But then you have a C++ class anyway. Keep a dictionary of HWND -> Window1
class, and have your window procedure use that dictionary to find the
Window1 object for a certain message.

Volker

"Bonj" <a@b.com> wrote in message
news:uO****************@TK2MSFTNGP09.phx.gbl...
我正在尝试创建一个类,它将包含实例化窗口并显示它的所有功能。我有一个SetWindowLong /
GetWindowLong对成功地将''this'指针存储在hWnd'的GWL_USERDATA中,但它所指的指针总是似乎
i''m trying to create a class that will contain all the features of
instantiating a window and showing it. I''ve got the SetWindowLong /
GetWindowLong pair to succesfully store the ''this'' pointer in the hWnd''s
GWL_USERDATA, but the pointer that it''s referring to always seems to


指向基类,而不是派生类。我不知道我
to the base class and never the derived class. I don''t know what I''m


错了,这让我疯了几个小时。因此,静态WndProc处理函数永远不会将消息路由到类的
wrong, this has been driving me mad for hours. Consequently, the static
WndProc handler function can never route the messages to the class''s


实际的

wndproc(它是虚拟的并在派生类中实现) ) - 它
wndproc (which is virtual and implemented in the derived class) - it


给出了

我的''纯虚函数调用''的一些低级调试错误....为什么
me some low-level debug error of ''pure virtual function call'' .... WHY


可以't


can''t

我看到派生类了吗?帮助!....
谢谢
I get it to see the derived class? help!....
Thanks




调用构造函数时创建的对象仍然是 ;执行Window1构造函数时,Window1"

对象。这就是C ++对象如何创建的工作原理 - 调用虚拟函数(或函数具有虚拟和/或
语义,即类似于你的'')。如果你希望你的类被子类化,那么构造函数(或析构函数)是没有意义的。


但是你还是有一个C ++类。保留HWND字典 - > Window1

类,并让你的窗口程序使用该字典查找特定消息的

Window1对象。


Volker


" Bonj" < a@b.com>在消息中写道

news:uO **************** @ TK2MSFTNGP09.phx.gbl ...
The object you create when calling the constructor is still a "Window1"
object when the Window1 constructor is executed. That''s how C++ object
creation works - calling virtual functions (or functions with a "virtual"
semantic, ie. like your''s) in the constructor (or the destructor) is
pointless if you expect your class to be subclassed.

But then you have a C++ class anyway. Keep a dictionary of HWND -> Window1
class, and have your window procedure use that dictionary to find the
Window1 object for a certain message.

Volker

"Bonj" <a@b.com> wrote in message
news:uO****************@TK2MSFTNGP09.phx.gbl...
i''我试图创建一个类,它将包含实例化窗口并显示它的所有功能。我已经有了SetWindowLong /
GetWindowLong对来成功地将''this'指针存储在hWnd'的GWL_USERDATA中,但它所指的指针总是似乎是
指向基类,而不是派生类。我不知道我做错了什么,这让我疯了几个小时。因此,静态的WndProc处理函数永远不会将消息路由到类的
实际的wndproc(它是虚拟的并在派生类中实现) - 它
给了我一些低 - 纯虚函数调用的级别调试错误....为什么
我不能看到派生类?帮助!....
谢谢
i''m trying to create a class that will contain all the features of
instantiating a window and showing it. I''ve got the SetWindowLong /
GetWindowLong pair to succesfully store the ''this'' pointer in the hWnd''s
GWL_USERDATA, but the pointer that it''s referring to always seems to point to the base class and never the derived class. I don''t know what I''m doing wrong, this has been driving me mad for hours. Consequently, the static
WndProc handler function can never route the messages to the class''s actual wndproc (which is virtual and implemented in the derived class) - it gives me some low-level debug error of ''pure virtual function call'' .... WHY can''t I get it to see the derived class? help!....
Thanks



这篇关于窗口类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆