📄 win.cpp
字号:
// Written by DKink|棼紫
// FileName : win.cpp
// Description: Generic Window Class
//-----------------------------------
#define STRICT
#define WIN32_LEAN_AND_MEAN
#include "StdAfx.h"
#include "win.h"
void KWindow::System_SetStateFunc(myFuncState state, myCallback value)
{
switch(state)
{
case my_FRAMEFUNC: procFrameFunc=value; break;
case my_RENDERFUNC: procRenderFunc=(myRenderFunc)value; break;
case my_FREEFUNC: procFreeFunc=value; break;
}
}
// Default message handler for main program window, dispatch to OnKeyDown, OnDraw, etc.
LRESULT KWindow::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch( uMsg )
{
case WM_KEYDOWN:
OnKeyDown(wParam, lParam);
return 0;
case WM_PAINT:
{
PAINTSTRUCT ps;
BeginPaint(m_hWnd, &ps);
OnDraw(ps.hdc);
EndPaint(m_hWnd, &ps);
}
return 0;
case WM_PALETTEISCHANGING: // should not happen
MessageBox(NULL, _T("Hello"), _T("Hi"), MB_OK);
return 0;
case WM_PALETTECHANGED:
return OnPaletteChanged(hWnd, wParam);
case WM_QUERYNEWPALETTE:
return OnQueryNewPalette();
case WM_DESTROY:
if ( m_bMainWindow )
PostQuitMessage(0); // main window only
return 0;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
// Generic window procedure passed to WIN32 API, dispatches to KWindow::WndProc
LRESULT CALLBACK KWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
KWindow * pWindow;
if ( uMsg==WM_NCCREATE )
{
assert( ! IsBadReadPtr((void *) lParam, sizeof(CREATESTRUCT)) );
MDICREATESTRUCT * pMDIC = (MDICREATESTRUCT *) ((LPCREATESTRUCT) lParam)->lpCreateParams;
pWindow = (KWindow *) (pMDIC->lParam);
assert( ! IsBadReadPtr(pWindow, sizeof(KWindow)) );
SetWindowLong(hWnd, GWL_USERDATA, (LONG) pWindow);
}
else
pWindow=(KWindow *)GetWindowLong(hWnd, GWL_USERDATA);
if ( pWindow )
return pWindow->WndProc(hWnd, uMsg, wParam, lParam);
else
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
// Register WNDCLASS for the window class. Registering only once
bool KWindow::RegisterClass(LPCTSTR lpszClass, HINSTANCE hInst)
{
WNDCLASSEX wc;
// Check if class is already registered
wc.cbSize = sizeof(wc);
if ( ! GetClassInfoEx(hInst, lpszClass, &wc) )
{
GetWndClassEx(wc); // fill class attributes
wc.hInstance = hInst;
wc.lpszClassName = lpszClass;
wc.hbrBackground = NULL;//背景没有
wc.hIcon = LoadIcon(hInst,MAKEINTRESOURCE(IDI_ICON_APP));
if ( !RegisterClassEx(&wc) ) // register
return false;
}
return true;
}
// Handles window creation
bool KWindow::CreateEx(DWORD dwExStyle, LPCTSTR lpszClass, LPCTSTR lpszName, DWORD dwStyle,
int nWidth, int nHeight, HWND hParent,
HMENU hMenu, HINSTANCE hInst)
{
//================================================================
if(NULL == procFrameFunc)
return false;
if (NULL == procRenderFunc)
return false;
//================================================================
if ( ! RegisterClass(lpszClass, hInst) )
return false;
// Use MDICREATESTRUCT to support MDI child window
MDICREATESTRUCT mdic;
memset(& mdic, 0, sizeof(mdic));
mdic.lParam = (LPARAM) this;
// Calculate the window size and position based upon the game size
m_iWidth = nWidth;
m_iHeight = nHeight;
int iWindowWidth = m_iWidth + GetSystemMetrics(SM_CXFIXEDFRAME) * 2,
iWindowHeight = m_iHeight + GetSystemMetrics(SM_CYFIXEDFRAME) * 2 +
GetSystemMetrics(SM_CYCAPTION);
iWindowHeight += GetSystemMetrics(SM_CYMENU);
int iXWindowPos = (GetSystemMetrics(SM_CXSCREEN) - iWindowWidth) / 2,
iYWindowPos = (GetSystemMetrics(SM_CYSCREEN) - iWindowHeight) / 2;
m_hWnd = CreateWindowEx(dwExStyle, lpszClass,
lpszName, dwStyle, iXWindowPos, iYWindowPos, nWidth, nHeight,
hParent, hMenu, hInst, & mdic);
// Create the offscreen device context and bitmap
HDC t_hdc = GetWindowDC(m_hWnd);
m_hOffscreenDC = CreateCompatibleDC(t_hdc);
m_hOffscreenBitmap = CreateCompatibleBitmap(t_hdc,
m_iWidth, m_iHeight);
ReleaseDC(m_hWnd,t_hdc);
SelectObject(m_hOffscreenDC, m_hOffscreenBitmap);
return m_hWnd!=NULL;
}
// Fill WNDCLASSEX, virtual function
void KWindow::GetWndClassEx(WNDCLASSEX & wc)
{
memset(& wc, 0, sizeof(wc));
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0; // CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = NULL;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
wc.lpszMenuName = NULL;
wc.lpszClassName = NULL;
wc.hIconSm = NULL;
}
WPARAM KWindow::MessageLoop(void)
{
MSG msg;
static int iTickTrigger = 0;
int iTickCount;
m_bMainWindow = true;
for(;;)
{
if (PeekMessage(&msg,NULL,0,0,PM_NOREMOVE))
{
GetMessage(&msg, NULL, 0, 0);
#ifdef _DEBUG
TCHAR temp[MAX_PATH];
wsprintf(temp, _T("Message(0x%x, 0x%x, 0x%x, 0x%x)\n"), msg.hwnd, msg.message, msg.wParam, msg.lParam);
OutputDebugString(temp);
#endif
if (msg.message == WM_QUIT) break;
//TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
iTickCount = GetTickCount();
if (iTickCount > iTickTrigger)
{
iTickTrigger = iTickCount + m_iFrameDelay;
//============================
//
if(procFrameFunc()) break;
//HandleKeys();
//====================================================
HDC hDC = GetDC(m_hWnd);
//使用白色背景
Rectangle(m_hOffscreenDC,0,0,m_iWidth,m_iHeight);
// Paint the game to the offscreen device context
procRenderFunc(m_hOffscreenDC);
// Blit the offscreen bitmap to the game screen
BitBlt(hDC, 0, 0, m_iWidth, m_iHeight,
m_hOffscreenDC, 0, 0, SRCCOPY);
// Cleanup
ReleaseDC(m_hWnd, hDC);
//=====================================================
//GameCycle();
}
else
{
//周期没到休息,这个就是降低CPU使用率的关键
Sleep(2);
}
}
}
if (NULL!=procFreeFunc)
{
procFreeFunc();
}
return msg.wParam;
}
// Common message processing for MDI Child Window
HRESULT KWindow::CommonMDIChildProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam,
HMENU hMenu, int nWindowMenu)
{
switch ( uMsg )
{
case WM_NCDESTROY: // should be the last message
SetWindowLong(hWnd, GWL_USERDATA, 0); // make sure no more message through WindowProc
delete this; // MDI child are created using new operator, time to delete
return 0;
case WM_MDIACTIVATE:
if ( lParam==(LPARAM) hWnd ) // if current window activate, switch menu
SendMessage(GetParent(hWnd), WM_MDISETMENU, (WPARAM) hMenu, (LPARAM) GetSubMenu(hMenu, nWindowMenu));
// send message to parent window to response to child window change
SendMessage(GetParent(GetParent(hWnd)), WM_USER, lParam!=(LPARAM) hWnd, 0);
return 0;
default:
// generic MDI child window message handling provided by OS
return DefMDIChildProc(hWnd, uMsg, wParam, lParam);
}
}
LRESULT KWindow::OnQueryNewPalette(void)
{
if ( m_hPalette==NULL )
return FALSE;
HDC hDC = GetDC(m_hWnd);
HPALETTE hOld= SelectPalette(hDC, m_hPalette, FALSE);
BOOL changed = RealizePalette(hDC) != 0;
SelectPalette(hDC, hOld, FALSE);
ReleaseDC(m_hWnd, hDC);
if ( changed )
{
OutputDebugString(_T("InvalidateRect\n"));
InvalidateRect(m_hWnd, NULL, TRUE); // repaint
}
return changed;
}
LRESULT KWindow::OnPaletteChanged(HWND hWnd, WPARAM wParam)
{
if ( ( hWnd != (HWND) wParam ) && m_hPalette )
{
HDC hDC = GetDC(hWnd);
HPALETTE hOld = SelectPalette(hDC, m_hPalette, FALSE);
if ( RealizePalette(hDC) )
if ( m_nUpdateCount >=2 )
{
InvalidateRect(hWnd, NULL, TRUE);
m_nUpdateCount = 0;
}
else
{
UpdateColors(hDC);
m_nUpdateCount ++;
}
SelectPalette(hDC, hOld, FALSE);
ReleaseDC(hWnd, hDC);
}
return 0;
}
int MyMessageBox(HWND hWnd, const TCHAR * text, const TCHAR * caption, DWORD style, int iconid)
{
MSGBOXPARAMS param;
memset(& param, 0, sizeof(param));
param.cbSize = sizeof(param);
param.hwndOwner = hWnd;
param.hInstance = GetModuleHandle(NULL);
param.lpszText = text;
param.lpszCaption = caption;
param.dwStyle = style | MB_USERICON;
param.lpszIcon = MAKEINTRESOURCE(iconid);
return MessageBoxIndirect(¶m);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -