您的位置:首页 > 编程语言

Windows程序编程(2):窗口创建

2016-11-21 11:10 525 查看

控制台窗口的的引入

在debug模式下控制台窗口的引入通过如下方式引入:

#ifdef _DEBUG   //主要用在debug模式下
AllocConsole();
freopen("conin$", "w", stdin);
freopen("conout$", "w", stdout);
#endif


Windows程序窗口介绍

窗口是windows操作系统应用程序的重要元素,是系统和用户交互的接口,每个windows应用程序至少拥有一个窗口,称为主窗口,窗口中一般包括:标题栏、菜单、最小化框、客户区等。

Windows程序消息机制

windows程序是基于时间驱动的程序设计;
windows程序和操作系统的通信都是通过消息完成的;
消息队列:
每个应用程序都有一个消息队列,程序中的事件都是以一个消息的形式存在被放到消息队列中,程序要通过循环不停地从消息队列中取消息进行相应的响应操作。

windows程序中消息的表现形式:MSG结构体

MSG:

typedef struct tagMSG {

    HWND        hwnd; //产生消息的窗口句柄

    UINT        message;//消息类型

    WPARAM      wParam;//参数,消息的扩展信息

    LPARAM      lParam;//参数,消息的扩展信息

    DWORD       time;//消息投递的时间

    POINT       pt;//消息投递时鼠标的坐标

}MSG;

Windows窗口创建

1、设计窗口类;注册窗口类;

2、设计窗口类,创建窗口;显示窗口;更新窗口;

3、消息循环;

4、消息处理;

窗口类:

#define MAX_LOADSTRING 100
#define ID_MOVE 10000
DWORD g_lastTime = 0;
// 全局变量:
HINSTANCE hInst;								// 当前实例
TCHAR szTitle[MAX_LOADSTRING];					// 标题栏文本
TCHAR szWindowClass[MAX_LOADSTRING];			// 主窗口类名

// 初始化全局字符串
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_WIN32PROJECT1, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);

//  函数:  MyRegisterClass()
//
//  目的:  注册窗口类。
//

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;

switch (message)
{
case WM_LBUTTONDOWN:
{
int xPos = GET_X_LPARAM(lParam);
int yPos = GET_Y_LPARAM(lParam);
cout << "lft" << endl;
}
break;
//	cout << "lb" << endl;
case WM_COMMAND:
wmId    = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// 分析菜单选择:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EX
4000
IT:
DestroyWindow(hWnd);
break;
case ID_MOVE:
//DestroyWindow(hWnd);
MoveWindow(hWnd, 500, 300, 400, 300, TRUE);
break;
case 10:
MessageBox(hWnd, _T("123"), _T("123"), MB_OK);
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO:  在此添加任意绘图代码...
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0); //发送退出程序消息
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}

ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;

wcex.cbSize = sizeof(WNDCLASSEX);//窗口大小

wcex.style			= CS_HREDRAW | CS_VREDRAW;//窗口的风格、样式
wcex.lpfnWndProc	= WndProc;//函数指针,窗口过程函数
wcex.cbClsExtra		= 0;//窗口类的附加内存
wcex.cbWndExtra		= 0;//窗口的附加内存
wcex.hInstance		= hInstance;//程序实例句柄
wcex.hIcon			= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WIN32PROJECT1));//图表句柄
wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);//背景画刷
wcex.lpszMenuName = NULL;//MAKEINTRESOURCE(IDC_WIN32PROJECT1);//菜单资源名
wcex.lpszClassName	= szWindowClass;//窗口类名字(自定义)
wcex.hIconSm		= LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));//小图标的句柄(托盘图表)

return RegisterClassEx(&wcex);
}


窗口句柄

句柄:类似ID号,资源标识
一个应用程序中可能有多个窗口,窗口被创建后返回一个句柄来标识该窗口。

其他句柄:如图表、光标等

消息循环

程序需要一直运行,必定有死循环;
Windows程序中就是实现消息循环让程序一直运行,并且触发窗口过程函数处理消息

while (GetMessage(&msg, NULL, 0, 0))//不断从消息队列中取消息,接收到WM_QUIT时返回0,没有消息时就一直等待
//	有消息时运行下面程序
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);//将虚拟键消息转化为字符消息,把消息放到消息队列中
DispatchMessage(&msg);//分发一个消息给窗口程序,让窗口过程函数处理消息
}
}
//  函数: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  目的: 处理主窗口的消息。
//
//  WM_COMMAND	- 处理应用程序菜单
//  WM_PAINT	- 绘制主窗口
//  WM_DESTROY	- 发送退出消息并返回
//窗口过程函数
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;

switch (message)
{
case WM_LBUTTONDOWN:
{
int xPos = GET_X_LPARAM(lParam);
int yPos = GET_Y_LPARAM(lParam);
cout << "lft" << endl;
}
break;
//	cout << "lb" << endl;
case WM_COMMAND:
wmId    = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// 分析菜单选择:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
case ID_MOVE:
//DestroyWindow(hWnd);
MoveWindow(hWnd, 500, 300, 400, 300, TRUE);
break;
case 10:
MessageBox(hWnd, _T("123"), _T("123"), MB_OK);
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);

EndPaint(hWnd,&ps);
break;
//GetObject(hBitmap,sizeof(BITMAP),&BITMAP);

case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}


窗口处理函数中就是对各种消息的响应函数,窗口过程函数也叫CALLBACK(回调函数),回调函数不用用户自己调用,系统自动调用。GetMessage函数:如果有消息则取出消息进行处理,如果没有消息则等待消息,直到有消息进入循环进行处理。
还有一个PeekMessage,与上面的GetMessage有所不同:

MSG msg = {0};
while(msg.message != WM_QUIT)
{
if(PeekMessage(&msg,0,0,0,PM_REMOVE))//有消息时处理消息并删除消息,还有一个PM_NOREMOVE,不删除
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
//随便你干什么
}

}



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: