我有一个C ++ Win32 Wrapper类的代码,我正在摆弄它。由于我只是尝试使用处理程序,我删除了WindowProcedure并且只使用了消息路由器。不知怎的,事情变得越来越多。 现在只有消息路由器,我已经厌倦了WindowClass的标题不会显示窗口的标题名称。 不知怎的,我似乎无法改变背景颜色。
Main.cpp的
#include "BaseWindow.h"
#include "GameWindow.h"
int APIENTRY WinMain ( HINSTANCE h_instance, HINSTANCE h_prev_instance, LPSTR lp_cmd_line, int n_cmd_show ) {
// Create the Game Window
GameWindow game_window ( h_instance, TEXT ( "GameWindow" ) );
game_window.Register ();
// Create the Base Window
BaseWindow base_window ( TEXT ( "BaseWindow" ), game_window.ClassName () );
base_window.Create ();
base_window.Show ();
// Pump Messages
MSG messages;
int status;
while ( ( status = GetMessage ( &messages, 0, 0, 0 ) ) != 0 ) {
if ( status == -1 ) {
// Break;
break;
}
TranslateMessage ( &messages );
DispatchMessage ( &messages );
}
return messages.wParam;
}
AbstractWindow.h
#pragma once
#ifndef __ABSTRACT_WINDOW_H__
#define __ABSTRACT_WINDOW_H__
#include <Windows.h>
class AbstractWindow {
public:
AbstractWindow ();
~AbstractWindow ();
virtual bool Create ();
static LRESULT CALLBACK MessageRouter ( HWND, UINT, WPARAM, LPARAM );
protected:
HWND hwnd_;
DWORD style_ex_;
LPCTSTR class_name_;
LPCTSTR window_name_;
DWORD style_;
int x_;
int y_;
int width_;
int height_;
HWND parent_;
HMENU menu_;
HINSTANCE h_instance_;
LPVOID param_;
// Default Handlers
virtual bool OnCreate ( HWND ) = 0;
virtual bool OnCommand ( int, int ) = 0;
virtual bool OnDestroy () = 0;
virtual bool EraseBackground ( HWND, WPARAM ) = 0;
virtual bool LeftButtonUp () = 0;
};
#endif // !__ABSTRACT_WINDOW_H__
AbstractWindow.cpp
#include "AbstractWindow.h"
AbstractWindow::AbstractWindow () {}
AbstractWindow::~AbstractWindow () {}
bool AbstractWindow::Create () {
hwnd_ = CreateWindowEx (
style_ex_,
class_name_,
window_name_,
style_,
x_,
y_,
width_,
height_,
parent_,
menu_,
h_instance_,
this // Pointer to this class instance
);
return ( !hwnd_ ? false : true );
}
LRESULT CALLBACK AbstractWindow::MessageRouter ( HWND hwnd, UINT message, WPARAM w_param, LPARAM l_param ) {
AbstractWindow* abstract_window = 0;
if ( message == WM_NCCREATE ) {
abstract_window = ( AbstractWindow* ) ( ( LPCREATESTRUCT ( l_param ) )->lpCreateParams );
SetWindowLong ( hwnd, GWL_USERDATA, long ( abstract_window ) );
abstract_window->OnCreate ( hwnd );
}
else {
abstract_window = ( AbstractWindow* ) ( GetWindowLong ( hwnd, GWL_USERDATA ) );
if ( abstract_window ) {
switch ( message ) {
case WM_COMMAND:
return abstract_window->OnCommand ( LOWORD ( w_param ), HIWORD ( w_param ) );
case WM_DESTROY:
return abstract_window->OnDestroy ();
case WM_ERASEBKGND:
return abstract_window->EraseBackground ( hwnd, w_param );
case WM_LBUTTONUP:
return abstract_window->LeftButtonUp ();
default:
return DefWindowProc ( hwnd, message, w_param, l_param );
}
}
else {
return DefWindowProc ( hwnd, message, w_param, l_param );
}
}
}
BaseWindow.h
#pragma once
#ifndef __BASE_WINDOW_H__
#define __BASE_WINDOW_H__
#include <Windows.h>
#include "AbstractWindow.h"
class BaseWindow : public AbstractWindow {
public:
BaseWindow ();
~BaseWindow ();
BaseWindow ( const TCHAR*, const TCHAR* );
// Display the window onto the screen while updating the client area
void Show ();
private:
virtual bool OnCreate ( HWND );
virtual bool OnCommand ( int, int );
virtual bool OnDestroy ();
virtual bool EraseBackground ( HWND, WPARAM );
virtual bool LeftButtonUp ();
};
#endif // !__BASE_WINDOW_H__
BaseWindow.cpp
#include "BaseWindow.h"
BaseWindow::BaseWindow () {}
BaseWindow::~BaseWindow () {}
BaseWindow::BaseWindow ( const TCHAR* window_name, const TCHAR* class_name ) : AbstractWindow () {
// Member variables are declaried in AbstractWindow as Protected
window_name_ = window_name;
class_name_ = class_name;
// Get the module handle for the window currently running
h_instance_ = GetModuleHandle ( NULL );
style_ = WS_OVERLAPPEDWINDOW | WS_VISIBLE;
x_ = CW_USEDEFAULT;
y_ = CW_USEDEFAULT;
width_ = CW_USEDEFAULT;
height_ = CW_USEDEFAULT;
parent_ = NULL;
menu_ = NULL;
}
void BaseWindow::Show () {
// hwnd_ is from AbstractWindow Class
ShowWindow ( hwnd_, SW_SHOW );
UpdateWindow ( hwnd_ );
}
// Handlers
bool BaseWindow::OnCreate (HWND hwnd) {
MessageBox ( hwnd, TEXT ( "[BaseWindow] Window has been successfully created!" ), TEXT ( "SUCCESS" ), MB_OK );
return true;
}
bool BaseWindow::OnCommand ( int ctrl_id, int notify_code ) {
// Lower 16 bits specifies the element the mouse was used on
// Upper 16 bits specifies the mouse properties
// ctrl_id = Lower
// notify_code = Upper
return true;
}
bool BaseWindow::OnDestroy () {
PostQuitMessage ( 0 );
return true;
}
bool BaseWindow::EraseBackground ( HWND hwnd, WPARAM w_param) {
RECT rect;
GetClientRect ( hwnd, &rect );
FillRect ( ( HDC ) w_param, &rect, GetSysColorBrush ( COLOR_BTNFACE ) );
return true;
}
bool BaseWindow::LeftButtonUp () {
return true;
}
GameWindow.h
#pragma once
#ifndef __GAME_WINDOW_H__
#define __GAME_WINDOW_H__
#include <Windows.h>
#include "AbstractWindow.h"
class GameWindow : protected WNDCLASSEX {
public:
GameWindow ();
~GameWindow ();
GameWindow ( HINSTANCE, const TCHAR* );
virtual bool Register ();
virtual const TCHAR* ClassName () const;
protected:
UINT cb_size_;
UINT style_;
WNDPROC lpfn_wnd_proc_;
int cb_cls_extra_;
int cb_wnd_extra_;
HINSTANCE h_instance_;
HICON h_icon_;
HCURSOR h_cursor_;
HBRUSH hbr_background_;
LPCTSTR lpsz_menu_name_;
LPCTSTR lpsz_class_name_;
HICON h_icon_sm_;
};
#endif // !__GAME_WINDOW_H__
GameWindow.cpp
#include "GameWindow.h"
GameWindow::GameWindow () {}
GameWindow::~GameWindow () {}
GameWindow::GameWindow ( HINSTANCE h_instance, const TCHAR* class_name ) {
// All messages belonging to this Window Class will get sent to MsgRouter
hInstance = h_instance;
lpszClassName = class_name;
lpfnWndProc = AbstractWindow::MessageRouter;
lpszMenuName = NULL;
cbSize = sizeof ( WNDCLASSEX );
cbClsExtra = NULL;
cbWndExtra = NULL;
style = CS_HREDRAW | CS_VREDRAW;
hIcon = LoadIcon ( NULL, IDI_APPLICATION );
hIconSm = LoadIcon ( NULL, IDI_APPLICATION );
hCursor = LoadCursor ( NULL, IDC_HAND );
hbrBackground = ( HBRUSH ) GetStockObject ( COLOR_BTNFACE );
}
const TCHAR* GameWindow::ClassName () const {
return lpszClassName;
}
bool GameWindow::Register () {
return ( ( RegisterClassEx ( this ) ) ? true : false );
}
答案 0 :(得分:0)
您的MessageRouter
缺少默认处理。如图所示添加DefWindowProc
LRESULT CALLBACK AbstractWindow::MessageRouter ( HWND hwnd, UINT message, WPARAM w_param, LPARAM l_param ) {
AbstractWindow* abstract_window = 0;
if ( message == WM_NCCREATE ) {
abstract_window = ( AbstractWindow* ) ( ( LPCREATESTRUCT ( l_param ) )->lpCreateParams );
SetWindowLong ( hwnd, GWL_USERDATA, long ( abstract_window ) );
abstract_window->OnCreate ( hwnd );
return DefWindowProc(hwnd, message, w_param, l_param);//ADD THIS LINE
}
...
对于后台,您可以处理WM_ERASEBKGND
,也可以设置hbrBackground
方法1:处理WM_ERASEBKGND
virtual LRESULT EraseBackground(HWND hwnd, WPARAM w_param)
{
RECT rect;
GetClientRect(hwnd, &rect);
FillRect((HDC)w_param, &rect, GetSysColorBrush(COLOR_BTNFACE));
return 1;
}
方法2:设置hbrBackground
并让窗口完成剩下的工作
hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
virtual LRESULT EraseBackground(HWND hwnd, WPARAM w_param)
{
//let window do this
return DefWindowProc(hwnd, WM_ERASEBKGND, w_param, 0);
}
......... 编辑#2
class AbstractWindow
{
virtual void OnPaint()=0;
...
};
AbstractWindow::MessageRouter()
{
case WM_PAINT:
abstract_window->OnPaint();
return 0;
...
}
void GameWindow::OnPaint()
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
TextOut(hdc, 0, 0, "Hello, Windows!", 15);
EndPaint(hwnd, &ps);
}