当然,使用界面库是可以写窗体程序的,但如果不使用界面库呢,如何写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,效果也是一样的。