一个窗口程序

 

#include "stdafx.h"
#include <windows.h>

LONG WINAPI WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpszCmdLine,
int nCmdShow)
{
WNDCLASS wc;
HWND hwnd;
MSG msg;
BOOL bRet;

/*
*初始化窗口
*/
wc.style = 0;
wc.lpfnWndProc = (WNDPROC)WndProc;//窗口程序地址
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;//实例句柄
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);//图标句柄
wc.hCursor = LoadCursor(NULL, IDC_ARROW);//光标句柄
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);//背景色
wc.lpszMenuName = NULL;
wc.lpszClassName = L"MyWdnClass";//加L把字符串转换成unicode字符串,
//这种字符串一个字符占两个字节 而一般ASCII字符是占一个字节
RegisterClass(&wc);//注册窗口

/*
*创建窗口
*/
hwnd = CreateWindow(L"MyWndClass",
L"SDK APPlication",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,//水平位置
CW_USEDEFAULT,//垂直位置
CW_USEDEFAULT,//初始化宽度
CW_USEDEFAULT,//初始化高度
HWND_DESKTOP,//父窗口句柄
NULL,//菜单句柄
hInstance,//程序实例句柄
NULL//窗口创建日期
);

ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);

while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0)
{
if (bRet == 0 || bRet == -1)
{
return -1;
}
else
{
TranslateMessage(&msg);//将虚拟键消息转换为字符消息
DispatchMessage(&msg);//将消息发送给窗口
}
}
return msg.wParam;

}

LRESULT CALLBACK WndProc(HWND hwnd,
UINT message,//消息ID
WPARAM wParam,
LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;

switch (message)
{
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);//获得设备环境句柄,准备指定的窗口来重绘并
//将绘画相关的信息放到一个PAINTSTRUCT结构中
Ellipse(hdc, 0, 0, 200, 100 );//绘制椭圆
EndPaint(hwnd, &ps);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}


return DefWindowProc(hwnd, message, wParam, lParam);
}

 

编译时出现错误信息:”无法解析的外部符号 _main,该符号在函数 ___tmainCRTStartup 中被引用“

然后在网上查找到了原因:这个问题表明你新建的是一个main类型函数(控制台程序),而你的程序中有窗口程序,显然是个win32函数,解决方法:
项目-属性-链接器-系统-子系统-把控制台该为windows

但还是出错,原因如下:


实在感觉不再爱了。。。。。。

 

 

WNDCLASS structure 

LpfnWndProc window proc, must be AfxWndProc
CbClsExtra not used (should be zero)
CbWndExtra not used (should be zero)
HInstance automatically filled with AfxGetInstanceHandle
HIcon icon for frame windows, see below
HCursor cursor for when mouse is over window, see below
HbrBackground background color, see below
LpszMenuName not used (should be NULL)
LpszClassName class name, see below

 

The MSG structure 

typedef struct tagMSG {     // msg  
    HWND   hwnd;      
    UINT   message;
    WPARAM wParam;
    LPARAM lParam;
    DWORD  time;
    POINT  pt;
} MSG;

The MSG structure contains message information from a thread’s message queue.

Members

hwnd

Identifies the window whose window procedure receives the message.

message

Specifies the message number.

wParam

Specifies additional information about the message. The exact meaning depends on the value of the message member.

lParam

Specifies additional information about the message. The exact meaning depends on the value of the message member.

time

Specifies the time at which the message was posted.

pt

Specifies the cursor position, in screen coordinates, when the message was posted. 

 

 

 

GetMessage以及消息循环说明

 

 在创建窗口、显示窗口、更新窗口后,我们需要编写一个消息循环,不断地从消息队列中取出消息,并进行响应。要从消息队列中取出消息,我们需要调用GetMessage()函数,该函数的原型声明如下:在创建窗口、显示窗口、更新窗口后,我们需要编写一个消息循环,不断地从消息队列中取出消息,并进行响应。要从消息队列中取出消息,我们需要调用GetMessage()函数,该函数的原型声明如下:

BOOL GetMessage(

          LPMSG lpMsg,              // address of structure with message

          HWND hWnd,                 // handle of window

          UINT wMsgFilterMin,       // first message

          UINT wMsgFilterMax        // last message

);

参数lpMsg指向一个消息(MSG)结构体,GetMessage从线程的消息队列中取出的消息信息将保存在该结构体对象中。

参数hWnd指定接收属于哪一个窗口的消息。通常我们将其设置为NULL,用于接收属于调用线程的所有窗口的窗口消息。

参数wMsgFilterMin指定要获取的消息的最小值,通常设置为0。

参数wMsgFilterMax指定要获取的消息的最大值。如果wMsgFilterMin和wMsgFilter Max都设置为0,则接收所有消息。

GetMessage函数接收到除WM_QUIT外的消息均返回非零值。对于WM_QUIT消息,该函数返回零。如果出现了错误,该函数返回-1,例如,当参数hWnd是无效的窗口句柄或lpMsg是无效的指针时。

 

BeginPaint

BeginPaint函数准备指定的窗口来重绘并将绘画相关的信息放到一个PAINTSTRUCT结构中。

参数:

  hWnd:[输入]被重绘的窗口HANDLE

  lpPaint:[输出]指向一个用来接收绘画信息的PAINTSTRUCT结构

  返回值:

  如果函数成功,返回值是指定窗口的显示设备内容HANDLE

  如果函数失败,返回值是NULL,指示没有得到显示设备内容

  Windows NT/2000/XP: 使用GetLastError得到更多的错误信息。

  备注:

  BeginPaint函数自动设置显示设备内容的剪切区域而排除任何更新区域外的区域更新区域通过InalidateRect或InalidateRgn函数和系统的改变大小、移动、创建、滚动或其他的影响客户区操作来设置的。如果更新区域被标记为可擦除的,BeginPaint发送一个WM_ERASEBKGND消息给窗口。

  一个应用程序除了响应WM_PAINT消息外,不应该调用BeginPaint。每次调用BeginPaint都应该有相应的EndPaint函数。

  如果被绘画的客户区中有一个^符号,BeginPaint自动隐藏该符号,而保证它不被擦除。

  如果窗口类有一个背景刷,BeginPaint使用这个刷子来擦除更新区域的背景。

 

posted @ 2014-03-31 22:48  RogerGold  阅读(161)  评论(0编辑  收藏  举报