Win32窗口程序实例

by admin on 2020年1月23日

WINDOWS程序内部运行原理

2009年2月19日4:15:43(第一次)**

API(Application programming interface) 应用程序编程的接口

MSG(message) 
消息结构体   

操作系统将每一个事件包装成一个称为消息MSG的结构体传递给应用程序

MSG的结构定义如下:(windows user interface : platform sdk )

Typedef struct tagMSG{

             
HWND hwnd;  窗口的句柄  句柄为资源的标识,按类型分为HICON HCURSOR HWND HINSTANCE

             
UINT message;      无符号整形具体的消息; 用宏来表示数值WM开头的为宏WM_*

             
WPARAM wParam; 
整型. 关于消息的附加信息. WM_CHAR消息字符的代码ASCII;

             
LPARAM lParam;   ;整型. 关于消息的附加信息. PARAM=PARAMETER参数,参量

             
DWORD time;      ;WORD16位的整数DWORD=Double WORD32位整数.指定消息的投递时间.

             
POINT pt;          当消息被投递的时候光标太屏幕上的坐标;

}MSG,*PMSG;

POINT为一个结构体定义了点x坐标y坐标

Typedef struct tagPOINT{

             
LONG x;

             
LONG y;

}
POINT,*PPOINT;                                                   
结束时间2009年2月19日4:57:49

2009年2月20日13:18:04(第二次)

消息:消息本身,特定的消息响应

WINMAN函数

入口点函数类似于C的MAN函数

int WINAPI WinMan(

             
HINSTANCE hInstance,     
//handle to cerrent instance  
实例(资源)的句柄,当前运行的句柄;

             
HINSTANCE hPrevinstance
//handle to previous instance 
先前实例的句柄,可能为空,兄弟的实例句柄

win32下这个实例总是为空(win98、2000等);

             
LPSTR lpCndLine,         
//command line 
LP->LONG POINTER长指针,ETRING字符串,指向字符

串的指针;类似于CHAR *  
命令行参数

             
int nCmdSbow             
//show state  显示的状态,比如窗口的大小全屏

);   //这个分号在具体的编程过程中是不要的,需要删除掉。

DOS下的MAIN函数可以接收2个参数:ARJc、ARJv. ARJc用来接受、存放命令行参数的个数,ARJv指针数组用来存放命令行参数,同样的在windows程序当中他也可以接收命令行的参数.

WINAPI :Calling convention for system functions.

2009年2月24日15:10:15(第三次)

窗口的创建。创建一个完整的窗口需要经过下面四个操作步骤:

l         设计一个窗口类;

l         注册窗口类;

l         创建窗口;

l         显示及更新窗口;

1、设计窗口。设计一个窗口就是设计一个窗口类,他是一个结构体

WNDCLASS

Typedef struct _WNDCLASS{     //MSDN–WNDCLASS

UINIT style;  
style //(Class Styles=CS)指定一个类的类型,这里是窗口类的类型;OR(|),与(&),取反(~),

                       赋值:wndclass.style=CS_HREDRAW | CS_VREDRAW (水平和垂直重画)

WNDPROC lpfnWndProc; 窗口过程。Lp=long pointer.fn=functionProc= procedure用来接收一个函数指针。

回掉函数(lpfnWndProc: Pointer to the
window procedure. You must use the

CallWindowProc[回调window进程] function to call the window procedure.
For more

information, see
WindowProc.)。这里我们会把一个窗口名赋给他(函数名相当于一个

函数的指针),即在设计的时候就确定了一个回调函数,这里给他赋了WinSunProc

这个函数,当然WinSunProc函数具体内容是什么需要程序员自己去编写。

int 
cbClsExtra;  
windows程序会为每一个类管理一个内部数据结构。类附加内存,通常情况下设为零.(=0)

澳门新葡亰网址下载,                         类额外的一个数据。(附加字节数)

int 
cbWndExtra; 
windows程序会为每一个窗口管理一个内部数据结构。窗口附加内存,通常情况下也设

置为零。以上两个分配额外的内存,通常我们不需要所以设置为零。(=0)

窗口类额外的一个数据。通常赋值为零表示我们不需要额外的内存,但是如果我们需要则额外的内存空间会自己变为零。这里设置为零就是=0,不同于其他的设置为NULL,因为这里是整数。

HANDLE 
hInstance;   代表我们当前程序的实例号。操作系统分配,直接通过WinMain的形参传递过来。

代表了我们当前应用程序的实例号,我们在设计窗口类的时候需要知道他是代表那

个应用程序实例的。从bInstance获得这个程序。

HICON  
hIcon;   图标的句柄。用LoadIcon这个函数来赋值 hIcon=LoadIcon(……)

HCURSOR 
hCursor; 光标句柄。用LoadCursor这个函数来赋值hCursor=LoadCursor(……)

HBRUSH 
hbrBackground; 
画刷的句柄,用的是GetStockObject()这么一个函数

LPCTSTR lpszMenuName;  LP=long point(32**位),CT=constant常量,STR=string.用来设定菜单的名字**;

可以直接设置为空NULL,如:lpszMenuNam=NULL;

 (如果这个类型不认识可以用data type 这个来查看不是SDK)

LPCTSTR lpszClassName;  设置一个类的名字(注册窗口的时候会用到),窗口设计完成之后需要给窗口取一

个名字。

}WNDCLASS,*PWNDCLASS;

这个函数是系统定义好了格式,我们只需要拿过来用,直接对参数进行赋值。

WindowProc 回调函数,窗口过程函数

LRESULT CALLBACK WindowProc(   //CALLBACK:窗口过程函数前边定义的时候加了一个CALLBACK

                                   
#define CALLBACK 
_stdcall

                                   
CALLBACK就是一个类型的定义

                                   
LRESULT就是一个长整型,返回一个结果码。

  HWND
hwnd,      // handle to
window

  UINT
uMsg,      // message
identifier

  WPARAM
wParam,  // first message
parameter

  LPARAM
lParam   // second message
parameter

);

DefWindowProc回调函数,窗口过程函数

LRESULT DefWindowProc(

  HWND
hWnd,      // handle to
window

  UINT
Msg,       // message
identifier

  WPARAM
wParam,  // first message
parameter

  LPARAM
lParam   // second message
parameter

);

_stdcall和_cdecl这是两种调用的约定,_stdcall标准调用约定,_cdecl为c语言的调用约定。标准调用约定也是PASCAL调用约定,dephi就是pascal调用约定。_stdcall和_cdecl在参数的传递顺序和堆栈的清除这两个方面有差异。Vc++默认的调用约定选项是_cdecl.需要时要经行定义。也可以通过Project -> Project Settings ->C/C++ ->Calling
convention:中选择_stdcall这种方式来设定。

LoadIcon

HICON LoadIcon(

    HINSTANCE hInstance, // handle to application instance 应用程序实例的一个句柄。当标准的图标加载的

时候这个参数用空(NULL),

LPCTSTR lpIconName 
// name string or resource identifier当第一个参数取值为NULL时第二个参数可以选择

);

如:LoadIcon(NULL,IDI_ERROR)     // ID=identifier

LoadCursor

HCURSOR LoadCursor(

HINSTANCE hInstance, // handle to application
instance 应用程序实例的一个句柄,如果想用一个标准的光标

这个参数需要设置为NULL

LPCTSTR lpCursorName  // name or resource identifier  同样当前一个参数设置为NULL是这个可以选择微

软提供的光标函数。

);

GetStockObject() 
获取一个笔、画刷、调色板、的句柄。**

HGDIOBJ GetStockObject(

  int
fnObject   // stock object
type

);

*=(HBRUSH) GetStockObject(WHITE_BRUSH);   // (HBRUSH) 这里是一个强制转换。因为GetStockObject返回的是一个GetStockObject的类型,而hbrBackground定义的为HBRUSH的类型,C++语言是一个强类型语言,对函数的类型要求的很严。强制类型转换必须要有可比性,即两个类型可以转换,这种转换在编译的时候不会报错但是在执行的时候会出现错误。

2、注册。窗口设置完之后需要对其进行注册(向操作系统注册),RegisterClass()窗口的注册函数

RegisterClass

ATOM RegisterClass(

  CONST
WNDCLASS *lpWndClass  // class
data 窗口类结构体的指针直接用定义的窗口类结构体的变量加上取

地址符&

);

3、创建一个窗口

首先需要定义一个句柄(HWND),利用这个句柄的变量保存我们新创建的窗口的标识。然后利用CreateWindow函数来进行窗口的创建。

HWND hwnd;

Hwnd=CreateWindow(……);

CreateWindow

HWND CreateWindow(

  LPCTSTR
lpClassName,  // registered class
name 注

  1. #include <windows.h>  

  2. //Win32窗口程序实例  

  3. //声明消息处理函数  

  4. LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);  

  5. char szClassName[]=”windowsclass”;  

  6. char szAppTitle[]=”WinApi窗口实例”;  

  7. int PASCAL WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd )  

  8. {  

  9.       

  10.     HWND hMainWnd;//窗口句柄  

  11.     MSG msg;//消息  

  12.     WNDCLASS winclass;//窗口结构体  

  13.     if(!hPrevInstance)  

  14.     {  

  15.         winclass.style=CS_HREDRAW|CS_VREDRAW;//窗口风格  

  16.         winclass.lpfnWndProc=WndProc;//注册消息处理函数  

  17.         winclass.cbWndExtra=0;//附加参数  

  18.         winclass.cbClsExtra=0;//附加参数  

  19.         winclass.hInstance=hInstance;//当前应用程序句柄  

  20.         winclass.hIcon=LoadIcon(NULL,IDI_APPLICATION);//加载窗口图标  

  21.         winclass.hCursor=LoadCursor(NULL,IDC_ARROW);//窗口光标  

  22.         winclass.hbrBackground=(HBRUSH)GetStockObject(LTGRAY_BRUSH);//设置窗口背景为浅灰色  

  23.         winclass.lpszMenuName=NULL;//窗口菜单为空  

  24.         winclass.lpszClassName=szClassName;//给窗体结构体命名  

  25.         RegisterClass(&winclass);//注册窗口  

  26.     }  

  27.     hMainWnd=CreateWindow(szClassName,//窗口结构体名称  

  28.         szAppTitle,//窗口标题  

  29.         WS_OVERLAPPEDWINDOW,//窗口风格为可重叠窗口  

  30.         CW_USEDEFAULT,CW_USEDEFAULT,//x,y坐标  

  31.         CW_USEDEFAULT,CW_USEDEFAULT,//窗口的宽度,高度  

  32.         NULL,NULL,hInstance,NULL);  

  33.     ShowWindow(hMainWnd,SW_SHOWNORMAL);//显示窗口  

  34.     UpdateWindow(hMainWnd);//更新窗口,最大化  

  35.     //建立消息循环  

  36.     while(GetMessage(&msg,NULL,0,0))  

  37.     {  

  38.           

  39.         TranslateMessage(&msg);  

  40.         DispatchMessage(&msg);  

  41.           

  42.     }  

  43.     return msg.wParam;  

  44. }  

  45. LRESULT CALLBACK WndProc(HWND hMainwnd,UINT message,WPARAM wParam,LPARAM lParam)  

  46. {  

  47.     switch(message)  

  48.     {  

  49.           

  50.     case WM_KEYDOWN://键盘按下  

  51.         {  

  52.               

  53.             MessageBox(hMainwnd,”键盘按下了”,”提示”,MB_OK);  

  54.             break;  

  55.         }  

  56.     case WM_LBUTTONDOWN://鼠标按下  

  57.         {  

  58.               

  59.             MessageBox(hMainwnd,”鼠标按下了”,”提示”,MB_OK);  

  60.             break;  

  61.         }  

  62.     case WM_RBUTTONDOWN://鼠标右键按下  

  63.         {  

  64.               

  65.             MessageBox(hMainwnd,”鼠标右键按下了”,”提示”,MB_OK);  

  66.             break;  

  67.         }  

  68.     case WM_DESTROY://关闭窗口  

  69.         {  

  70.               

  71.             MessageBox(hMainwnd,”关闭窗口了”,”提示”,MB_OK);  

  72.             PostQuitMessage(0);  

  73.             //exit(0);  

  74.             //ExitProcess(0);  

  75.             break;  

  76.         }  

  77.     default:  

  78.         break;  

  79.     }  

  80.     return DefWindowProc(hMainwnd,message,wParam,lParam);  

  81.       

  82. }  

用Windows API编写出来的窗口怎么才能显示另一份.cpp文件的结果
#include
#include
#include
#include
using namespace std;
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
//主函数 程序入口

[cpp] view
plaincopy

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR
szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT (“HelloWin”) ;
HWND hwnd ;
//用来保存成功创建窗口后返回的句柄
MSG msg ;
//定义消息结构体变量
WNDCLASS wndclass ;
//窗体类
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
//指定窗口风格
wndclass.lpfnWndProc = WndProc ;
////函数指针,指向处理窗口消息的函数入口
wndclass.cbClsExtra = 0 ; //结构体后附加的字节数,一般总为0
wndclass.cbWndExtra = 0 ; //窗体实例附加的字节数,一般总为0
wndclass.hInstance = hInstance ; //模块句柄
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ; //图标句柄
任务栏显示的图标
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ; //光标句柄
wndclass.hbrBackground=GetStockObject(BLACK_BRUSH);
//背景颜色COLOR_BACKGROUND
wndclass.lpszMenuName = NULL ; //菜单名的字符串
wndclass.lpszClassName = szAppName ; //自定义类名,不要与其他类名重复
if (!RegisterClass (&wndclass))
{
MessageBox (NULL, TEXT , szAppName, MB_ICONERROR) ;
return 0 ;
}
int x =((GetSystemMetrics(SM_CXSCREEN)/2)-200); //x居中
int y =((GetSystemMetrics(SM_CYSCREEN)/2)-200); //y居中
//创建窗体api
hwnd =
CreateWindow(szAppName,TEXT(“NTFS文件检索”),WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX,x,y,400,400,NULL,NULL,hInstance,NULL);
//显示窗体的API 传入需要显示的窗体句柄和显示方式
ShowWindow(hwnd,iCmdShow); //刷新窗体的API
UpdateWindow; //从系统的应用程序线程消息队列中取得一个消息
while(GetMessage(&msg,NULL,0,0) > 0)
{
DispatchMessage;
}
return msg.wParam;
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM
lParam)
{
HDC hdc; //句柄
PAINTSTRUCT ps;
RECT rect; //矩形
HINSTANCE hInstance; //窗口实例
static HWND hwndButton[10]; //按钮句柄
switch
{
case WM_CREATE: //创建按钮
{
//HWND CreateWindow(LPCTSTR lpClassName,LPCTSTR lpWindowName,DWORD
dwStyle,int x,int y,int nWidth,int nHeight,HWND hWndParent,HMENU
hMenu,HANDLE hlnstance,LPVOID lpParam);

  1. // 内容:一个基本的Win32程序框架  

  2. #include <windows.h>  

  3. //#include <windowsx.h>  

  4. //函数声明  

  5. BOOL InitWindow( HINSTANCE hInstance, int nCmdShow );  

  6. LRESULT CALLBACK WinProc( HWND hWnd, UINT message, WPARAM wParam,LPARAM lParam );  

  7.   

  8. //函数:WinMain() 功能:Win32应用程序入口函数。创建主窗口,处理消息循环  

  9. int PASCAL WinMain( HINSTANCE hInstance, //当前实例句柄  

  10.                    HINSTANCE hPrevInstance, //前一个实例句柄  

  11.                    LPSTR lpCmdLine, //命令行字符  

  12.                    int nCmdShow) //窗口显示方式  

  13. {  

  14.     MSG msg;  

  15.     //创建主窗口  

  16.     if ( !InitWindow( hInstance, nCmdShow ) )  

  17.         return FALSE;  

  18.     //进入消息循环:     

  19.     //从该应用程序的消息队列中检取消息,送到消息处理过程,      

  20.     //当检取到WM_QUIT消息时,退出消息循环。      

  21.     while (GetMessage(&msg, NULL, 0, 0))          

  22.     {                 

  23.         TranslateMessage(&msg);       

  24.         DispatchMessage(&msg);        

  25.     }  

  26.     //程序结束  

  27.     return msg.wParam;  

  28. }  

  29. //函数:InitWindow()  

  30. //功能:创建窗口。  

  31. static BOOL InitWindow( HINSTANCE hInstance, int nCmdShow )  

  32. {  

  33.     HWND hwnd; //窗口句柄     

  34.     WNDCLASS wc; //窗口类结构      

  35.     //填充窗口类结构     

  36.     wc.style = CS_VREDRAW | CS_HREDRAW;   

  37.     wc.lpfnWndProc = (WNDPROC)WinProc;    

  38.     wc.cbClsExtra = 0;    

  39.     wc.cbWndExtra = 0;    

  40.     wc.hInstance = hInstance;     

  41.     wc.hIcon = LoadIcon( hInstance, IDI_APPLICATION );    

  42.     wc.hCursor = LoadCursor( NULL, IDC_ARROW );   

  43.     wc.hbrBackground =(HBRUSH)GetStockObject(WHITE_BRUSH);    

  44.     wc.lpszMenuName = NULL;   

  45.     wc.lpszClassName = “EasyWin”;     

  46.     RegisterClass( &wc );          //注册窗口类    

  47.     hwnd = CreateWindow(        //创建主窗口       

  48.         “EasyWin”, //窗口类名称        

  49.         “一个基本的Win32程序”, //窗口标题        

  50.         WS_OVERLAPPEDWINDOW, //窗口风格,定义为普通型        

  51.         100, //窗口位置的x坐标       

  52.         100, //窗口位置的y坐标       

  53.         400, //窗口的宽度          

  54.         300, //窗口的高度      

  55.         NULL, //父窗口句柄         

  56.         NULL, //菜单句柄      

  57.         hInstance, //应用程序实例句柄         

  58.         NULL ); //窗口创建数据指针    

  59.     if( !hwnd )  

  60.         return FALSE;     

  61.     //显示并更新窗口     

  62.     ShowWindow( hwnd, nCmdShow );     

  63.     UpdateWindow( hwnd );  

  64.     return TRUE;      

  65. }  

  66. //函数:WinProc()  

  67. //功能:处理主窗口消息  

  68. LRESULT CALLBACK WinProc( HWND hWnd, UINT message, WPARAM wParam,LPARAM lParam )  

  69. {  

  70.     switch( message )  

  71.     {         

  72.     case WM_KEYDOWN://击键消息        

  73.         switch( wParam )              

  74.         {             

  75.         case VK_ESCAPE:           

  76.             MessageBox(hWnd,”ESC键按下了!”,”Keyboard”,MB_OK);             

  77.             break;            

  78.         }         

  79.         break;        

  80.         case WM_RBUTTONDOWN://鼠标消息            

  81.             {                 

  82.                 MessageBox(hWnd,”鼠标右键按下了!”,”Mouse”,MB_OK);                

  83.                 break;                

  84.             }             

  85.         case WM_PAINT://窗口重画消息            

  86.             {                 

  87.                 char hello[]=”你好,我是EasyWin !”;                

  88.                 HDC hdc;                  

  89.                 PAINTSTRUCT ps;           

  90.                 hdc=BeginPaint( hWnd,&ps ); //取得设备环境句柄            

  91.                 SetTextColor(hdc, RGB(0,0,255)); //设置文字颜色             

  92.                 TextOut( hdc, 20, 10, hello, strlen(hello) );//输出文字           

  93.                 EndPaint( hWnd, &ps ); //释放资源             

  94.                 break;            

  95.             }         

  96.         case WM_DESTROY://退出消息            

  97.             PostQuitMessage( 0 );//调用退出函数             

  98.             break;            

  99.     }  

  100.     //调用缺省消息处理过程      

  101.     return DefWindowProc(hWnd, message, wParam, lParam);      

  102. }  

 hInstance = ((LPCREATESTRUCT)lParam)->hInstance; //按钮1 hwndButton[0] = CreateWindow("BUTTON","检索盘符", WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, 10,10,100,100,hwnd,NULL, (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), NULL); //按钮2 hwndButton[1] = CreateWindow("BUTTON","查询", WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, 290,120,100,100,hwnd,NULL, (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), NULL); hwndButton[3] = CreateWindow("BUTTON","获取历史记录", WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, 290,260,100,100,hwnd,NULL, (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), NULL); hwndButton[4] = CreateWindow("LISTBOX","盘符栏",WS_VISIBLE|WS_VSCROLL|WS_CHILD,120,10,160,100,hwnd,NULL, (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), NULL); hwndButton[5] = CreateWindow("EDIT","输入栏",WS_VISIBLE|WS_CHILD,10,120,270,20,hwnd,NULL, (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), NULL); hwndButton[6] = CreateWindow("LISTBOX","结果栏",WS_VISIBLE|WS_VSCROLL|WS_CHILD,10,150,270,210,hwnd,NULL, (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), NULL); return 0;}/*case WM_PAINT: //绘制文字 hdc = BeginPaint(hwnd,&ps); TextOut(hdc,300,200,button[iFlag].szText,lstrlen(button[iFlag].szText)); EndPaint(hwnd,&ps); GetClientRect(hwnd,&rect); DrawText(hdc,TEXT("By:Eastmount CSDN制作"),-1,&rect,DT_SINGLELINE|DT_CENTER|DT_VCENTER); EndPaint(hwnd,&ps); return 0;*/case WM_COMMAND: //响应按钮消息 iflParam == hwndButton[0]) { ///MessageBox(NULL,TEXT("是否训练图片?"),TEXT,MB_YESNO|MB_ICONQUESTION); } iflParam == hwndButton[1]) { MessageBox(NULL,TEXT("是否获取图片?"),TEXT,MB_YESNO|MB_ICONQUESTION); } return 0;case WM_CLOSE: //关闭 if(IDYES==MessageBox(hwnd,"是否关闭程序?","提示",MB_YESNO|MB_ICONQUESTION)) { DestroyWindow ; } return 0;case WM_DESTROY: //退出程序 PostQuitMessage  ; return 0 ;}return DefWindowProc (hwnd, message, wParam, lParam) ;

}

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图