|
電腦遊戲製作開發設計論壇 任何可以在PC上跑的遊戲都可以討論,主要以遊戲之製作開發為主軸,希望讓台灣的遊戲人有個討論、交流、教學、經驗傳承的園地
|
上一篇主題 :: 下一篇主題 |
發表人 |
內容 |
babu61509 散播福音的祭司
註冊時間: 2007-08-26 文章: 142
681.01 果凍幣
|
發表於: 2009-5-7, AM 9:44 星期四 文章主題: [實用&教學包裝] win32 基礎視窗 [1.0c UA] 2011/08/13 更新 |
|
|
2011/08/03 新增 Unicode 版本,會依專案屬性自動變換。
2011/08/03 新增 1.0a UA版,修正初始化順序不正確導致指定的標題跟視窗位置大小無效的bug。
2011/08/04 新增 1.0b UA版,新增DefMP預設視窗訊息處理、resetLocation()置中視窗位置。
2011/08/13 新增 1.0c UA版,改用#infdef判斷是否重複讀入,使用AdjustWindowRect來計算Client Rect大小。
已經包起來了,先發表來佔個位置,有興趣的人可以稍微看一下,等有空再來好好的修一下註解等等。
.h內容(取WinFormA):
代碼: |
class WinFormA{
private:
HWND ConsoleHwnd; // Console 的 HWND
HWND Hwnd; // 建立出來的 Windows HWND
HINSTANCE Hinstance; // 建立出來的 Windows HINSTANCE
string WinTitle; // 建立出來 Windows 的標題文字
string ClassName;
WNDCLASSEX wc;
void Init(); // 初始化函式
void CreateWin(); // 建立視窗
int X,Y,Width,Height; // 視窗位置大小
static LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); // 視窗事件處理函式
LRESULT MyMsg( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); //
INT WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ); // 主視窗函式
public:
WinForm(); // 建構式
WinForm(string Win_Title); // 建構式(視窗標題名稱)
WinForm(string Win_Title, int x , int y , int width , int height); // 建構式(視窗標題名稱,X位置,Y位置,視窗寬度,視窗高度)
~WinForm(); // 解構式
static LRESULT DefMP( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); // 預設訊息處理
HWND GetHWND(); // 取得視窗的 HWND
void ShowConsole(bool Show); // 是否顯示 Console 視窗
int Show(); // 顯示 Windows 視窗
void resetLocation(); // 置中視窗
int (*MyMainLoop)(); // 自訂主迴圈函式
LRESULT (*MyMsgProc)( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); // 自訂視窗處理函式
};
|
使用方法 :
1. 建立一個空白視窗。
代碼: |
#include "WinForm.h"
void main()
{
WinForm *form1 = new WinForm();
form1->Show();
delete form1;
}
|
2. 建立一個標題為 我自己的視窗 的視窗。
代碼: |
#include "WinForm.h"
void main()
{
WinForm *form1 = new WinForm("我自己的視窗");
form1->Show();
delete form1;
}
|
3. 建立一個標題為 我自己的視窗 ,位置在(100,100),寬為800,高為600像素的視窗。
代碼: |
#include "WinForm.h"
void main()
{
WinForm *form1 = new WinForm("我自己的視窗",100,100,800,600);
form1->Show();
delete form1;
}
|
自訂主迴圈函式與視窗訊息函式:
代碼: |
#include "WinForm.h"
int mymainfun(){
return 0;
}
LRESULT mymsg( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){
switch( msg )
{
case WM_DESTROY:
PostQuitMessage( 0 );
return 0;
}
return DefWindowProc( hWnd, msg, wParam, lParam );
}
void main()
{
WinForm *form1 = new WinForm();
form1->MyMainLoop = mymainfun; // 自訂主迴圈
form1->MyMsgProc = mymsg; // 自訂視窗訊息
form1->Show();
delete form1;
}
|
取得視窗HWND方法 :
代碼: |
HWND hwnd = form1->GetHWND();
|
Console被當為偵錯視窗,要顯示可以呼叫
代碼: |
form1->ShowConsole(true);
|
置中視窗位置:
代碼: |
form1->resetLocation();
|
超簡單的吧 ? 這樣win32基礎的第一步就踏出來了 ! (炸
參考資料 :
I want the HWND and HINSTANCE of a console window. How do I get it?
theForger's Win32 API教程第二版(簡體中文)
如何取得主控台視窗控制代碼 (HWND)
D - Mr. Bright: static WndProc
本論壇壇主yag
描述: |
|
下載 |
檔名: |
WinForm.rar |
附件大小: |
3.49 KB |
下載次數: |
共 1188 次 |
_________________ 已經畢業了!!
babu61509 在 2011-8-13, PM 9:55 星期六 作了第 14 次修改 |
|
回頂端 |
|
|
happylin 略有貢獻的成員
註冊時間: 2007-07-26 文章: 70
127.34 果凍幣
|
發表於: 2009-5-8, AM 11:37 星期五 文章主題: |
|
|
這個程式有bug (也不能算是很嚴重的bug)
就是危反. 有借有還 再借不難的原則
new 了一個WinForm 可是沒有 delete
且沒有~WinForm() 的設計..
|
|
回頂端 |
|
|
babu61509 散播福音的祭司
註冊時間: 2007-08-26 文章: 142
681.01 果凍幣
|
發表於: 2009-5-8, PM 12:02 星期五 文章主題: |
|
|
happylin 寫到: | 這個程式有bug (也不能算是很嚴重的bug)
就是危反. 有借有還 再借不難的原則
new 了一個WinForm 可是沒有 delete
且沒有~WinForm() 的設計.. |
解構式沒寫是因為,剛開始想說還沒用到指標類的東西,暫時先放在一旁,結果後來忘了寫上去XD
現在補上去了。
_________________ 已經畢業了!! |
|
回頂端 |
|
|
skyvoice 偶而上來逛逛的過客
註冊時間: 2009-01-22 文章: 14
128.78 果凍幣
|
發表於: 2009-5-8, PM 1:06 星期五 文章主題: |
|
|
這個檔案是之前到數位內容學院進修後並經過改良的版本,參考看看吧~
描述: |
|
下載 |
檔名: |
WindowFrame Beta 1.rar |
附件大小: |
6.66 KB |
下載次數: |
共 1283 次 |
|
|
回頂端 |
|
|
damody 偶而上來逛逛的過客
註冊時間: 2009-05-18 文章: 8
81.28 果凍幣
|
發表於: 2009-9-7, AM 10:56 星期一 文章主題: 太大膽的寫法了= = |
|
|
你竟然敢直接用LPCTSTR,真的是太誇張了= =
也不讓人從外面傳winproc
好吧,雖然我的也不是很好,不過還是放上來一下
.h
代碼: | #ifndef Win32Class_Im40eda407m1229c278a93mm7e5f_H
#define Win32Class_Im40eda407m1229c278a93mm7e5f_H
// Windows 標頭檔:
#include <windows.h>
class Win32Class
{
public:
Win32Class(void);
HWND ToCreateWindow(int x, int y, int width, int height, const wchar_t *title, LRESULT (_stdcall *wndporc)(HWND, UINT, WPARAM, LPARAM) = &Win32Class::Proc);
MSG HandlePeekMessage(void);
HWND GetHandle(void);
HINSTANCE GetInstance(void);
RECT GetRect(void);
void GetMouseState(int &x, int &y, int button[3]);
void ToShow(void);
void ToHide(void);
void ToMove(UINT x, UINT y, UINT nWidth, UINT nHeight, bool bRepaint = true);
static LRESULT CALLBACK Proc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
private:
HWND m_hWnd;
HINSTANCE m_hInstance;
};
#endif // Win32Class_Im40eda407m1229c278a93mm7e5f_H |
.cpp
代碼: |
/*
這是一個專門產生視窗的類別,像下面這樣,處理訊息的函數,必需從外面提供給ToCreateWindow,否則會使用預設的函數。
LRESULT CALLBACK Proc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
ToCreateWindow的前五項函數是用來描述視窗的,第六項就是要像上面的函數, 記得要儲存回傳的HWND控制碼。
GetHandle只能得到最後一個視窗的控制碼。
注意!!!在無限迴圈中必需自行呼叫HandlePeekMessage來處理訊息。
GetMouseState可以獲得滑鼠狀態。
*/
#include "Win32Class.h"
Win32Class::Win32Class(void)
{
m_hInstance = GetModuleHandle(NULL);
}
HWND Win32Class::ToCreateWindow(int x, int y, int width, int height, const wchar_t *title, LRESULT (_stdcall *wndporc)(HWND, UINT, WPARAM, LPARAM)/*= &Win32Class::Proc*/)
{
WNDCLASS window_class;
memset(&window_class, 0, sizeof(WNDCLASS));
// `設定視窗型態`
window_class.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
// `設定訊息處理函式為WndProc`
window_class.lpfnWndProc = wndporc;
// `取得目前執行的程式`
window_class.hInstance = m_hInstance;
// `使用內定的滑鼠游標`
window_class.hCursor = LoadCursor(NULL, IDC_ARROW);
// `背景設為黑色, 其實有沒有設都沒差.`
window_class.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
// `給定一個註冊視窗時使用的名字`
window_class.lpszClassName = title;
// `跟作業系統註冊一個新的視窗`
if (RegisterClass(&window_class) == 0)
{
return false;
}
// `計算視窗的邊線會佔掉的點數, 必要時要增加視窗大小.`
RECT window_rect;
SetRect(&window_rect, x, y, x+width, y+height);
AdjustWindowRect(&window_rect, WS_OVERLAPPEDWINDOW, FALSE); //WS_POPUPWINDOW是單框線視窗
// `準備工作完成, 開啟一個視窗.`
HWND window_handle = CreateWindowEx(
WS_EX_APPWINDOW,
title,
title,
WS_OVERLAPPEDWINDOW,
window_rect.left, // x
window_rect.top, // y
window_rect.right - window_rect.left, // width
window_rect.bottom - window_rect.top, // height
NULL,
NULL,
window_class.hInstance,
NULL
);
if (window_handle == NULL)
return false;
m_hWnd = window_handle;
return window_handle;
}
MSG Win32Class::HandlePeekMessage()
{
MSG msg;
// 主訊息迴圈:
if ( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) )
{
// `有訊息的話, 就把它送給訊息處理函式.`
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg;
}
HWND Win32Class::GetHandle(void)
{
return m_hWnd;
}
HINSTANCE Win32Class::GetInstance(void)
{
return m_hInstance;
}
void Win32Class::GetMouseState(int &x, int &y, int button[3])
{
POINT p;
GetCursorPos(&p);
ScreenToClient(m_hWnd, &p);
x = p.x;
y = p.y;
button[0] = GetKeyState(VK_LBUTTON) & 0x80 ? 1 : 0;
button[1] = GetKeyState(VK_MBUTTON) & 0x80 ? 1 : 0;
button[2] = GetKeyState(VK_RBUTTON) & 0x80 ? 1 : 0;
}
void Win32Class::ToShow(void)
{
// `顯示視窗`
ShowWindow(m_hWnd, SW_SHOWNORMAL);
SetActiveWindow(m_hWnd);
}
void Win32Class::ToHide(void)
{
// `顯示視窗`
ShowWindow(m_hWnd, SW_HIDE);
SetActiveWindow(m_hWnd);
}
void Win32Class::ToMove( UINT x, UINT y, UINT nWidth, UINT nHeight, bool bRepaint /*= true*/ )
{
MoveWindow(m_hWnd , x, y, nWidth, nHeight, bRepaint);
}
RECT Win32Class::GetRect( void )
{
RECT rect;
GetWindowRect(m_hWnd, &rect);
return rect;
} |
_________________ 有心情就是有壓力^^ |
|
回頂端 |
|
|
|
|
您 無法 在這個版面發表文章 您 無法 在這個版面回覆文章 您 無法 在這個版面編輯文章 您 無法 在這個版面刪除文章 您 無法 在這個版面進行投票 您 可以 在這個版面附加檔案 您 可以 在這個版面下載檔案
|
|