當然,使用界面庫是可以寫窗體程序的,但如果不使用界面庫呢,如何寫win32窗體程序呢?
#include <windows.h>
#include <stdio.h>
HINSTANCE g_hInst = NULL;//定義全局靜態變量,不會和別的cpp文件中的同名變量衝突
HWND txtInput1;
HWND txtInput2;
HWND chkSel[4];
HWND cmdStart;
HWND txtOutput;
//消息處理函數,每個窗體都有一個,如果寫在WinMain後面,則要先聲明
LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
switch(Message)
{
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_CREATE://創建主窗口時在上面創建輸入框和按鈕控件
txtInput1 = CreateWindowEx(WS_EX_CLIENTEDGE,"Edit","",WS_CHILD|WS_VISIBLE,10,10,100,20,hwnd,NULL,g_hInst,0);
txtInput2=CreateWindowEx(WS_EX_CLIENTEDGE,"Edit","",WS_CHILD|WS_VISIBLE,10,40,100,20,hwnd,NULL,g_hInst,0);
chkSel[0]=CreateWindowEx(0,"Button","+",WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON,10,70,35,20,hwnd,NULL,g_hInst,0);
chkSel[1]=CreateWindowEx(0,"Button","-",WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON,50,70,35,20,hwnd,NULL,g_hInst,0);
chkSel[2]=CreateWindowEx(0,"Button","*",WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON,90,70,35,20,hwnd,NULL,g_hInst,0);
chkSel[3]=CreateWindowEx(0,"Button","/",WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON,130,70,35,20,hwnd,NULL,g_hInst,0);
SendMessage(chkSel[0],BM_SETCHECK,1,0);//默認選中了“+”
cmdStart=CreateWindowEx(0,"Button","開始計算",WS_CHILD|WS_VISIBLE,10,100,70,30,hwnd,NULL,g_hInst,0);
txtOutput=CreateWindowEx(WS_EX_CLIENTEDGE,"Edit","",WS_CHILD|WS_VISIBLE,10,140,100,20,hwnd,NULL,g_hInst,0);
break;
case WM_COMMAND:
if((HWND)lParam==cmdStart)
{//按了“開始計算”按鈕
double n1,n2;
double jg;
char ts[100];
GetWindowText(txtInput1,ts,sizeof(ts));
n1=atof(ts);
GetWindowText(txtInput2,ts,sizeof(ts));
n2=atof(ts);
if(SendMessage(chkSel[0],BM_GETCHECK,0,0))
{
jg=n1+n2;
}
else if(SendMessage(chkSel[1],BM_GETCHECK,0,0))
{
jg=n1-n2;
}
else if(SendMessage(chkSel[2],BM_GETCHECK,0,0))
{
jg=n1*n2;
}
else
{
jg=n1/n2;
}
snprintf(ts,sizeof(ts),"%g",jg);
SetWindowText(txtOutput,ts);
}
break;
default:
//爲確保每一個消息都得到處理,調用默認的消息處理函數來處理其它消息
return DefWindowProc(hwnd, Message, wParam, lParam);
}
return 0;
}
//Windows窗體程序主函數
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX WndClass; //定義窗口類,有下面12種屬性
HWND hwnd; //定義HWND類型變量hwnd,其實HWND就是UINT類型
MSG Msg;
char const g_szClassName[] = "MyWindowClass";//因爲有兩個地方用到了類名
g_hInst = hInstance;
WndClass.cbSize = sizeof(WNDCLASSEX); //類大小,可省略
WndClass.style = 0;
WndClass.lpfnWndProc = WndProc; //關聯消息處理函數,見下LRESULT CALLBACK WndProc()
WndClass.cbClsExtra = 0;
WndClass.cbWndExtra = 0;
WndClass.hInstance = g_hInst;
WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); //圖標
WndClass.hIconSm = LoadIcon(NULL, IDI_APPLICATION); //可省略
WndClass.hCursor = LoadCursor(NULL, IDC_ARROW); //光標
WndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW);
WndClass.lpszMenuName = "MyWin";
WndClass.lpszClassName = g_szClassName;
if(!RegisterClassEx(&WndClass)) //如果註冊失敗,則顯示錯誤信息並退出
{
MessageBox(0, "Window Registration Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK | MB_SYSTEMMODAL);
return 0;
}
hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
g_szClassName,
"File Editor Example Program",//窗體名
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 320, 240,
NULL, NULL, g_hInst, NULL);
if(hwnd == NULL)
{
MessageBox(0, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK | MB_SYSTEMMODAL);
return 0;
}
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
while(GetMessage(&Msg, NULL, 0, 0)) //從消息隊列中取消息
{
TranslateMessage(&Msg); //轉換消息
DispatchMessage(&Msg); //派發消息,由這裏激活LRESULT CALLBACK WndProc()函數
}
return Msg.wParam;
}
int main(int argc,char *argv[])
{
FreeConsole();//釋放控制檯
WinMain(GetModuleHandle(NULL),NULL,GetCommandLine(),5);
return 1;
}
這樣就可以利用win32提供的API來寫窗體程序了,只是程序運行前,會有一個控制檯窗口一閃而過,但這個問題可以通過最小化運行來解決。
==============================================================================
2019-04-03解決運行時CMD窗口閃一下的問題,參考網址:https://www.cnblogs.com/elitiwin/p/5341304.html
那就是右擊codelite中的本項目,點設置,在鏈接器選項中,加入 -Wl,--subsystem,windows 即可,這樣的話這句Freeconsole();不需要有了。或者加參數-mwindows,效果也是一樣的。