windows程序设计知识点

 

.WINAPI解析

           #define WINAPI   __stdcall

    该语句指定了一个调用约定,包括如何生成机器代码以在堆栈中放置函数调用的参数,许多windows函数调用声明为WINAPI

 

          注意:#define CALLBACK  __stdcall

               CALLBACK也定义成__stdcall,但CALLBACK常用于回调函数,比如说窗口过程

 

例如:

     LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wparam,LPARAM lParam)

      {

                           ........................

                          ..........................

                    }

 

具体用WINAPI还是CALLBACK更加具体情况,方便记忆原则,比如说callback,看名次就知道是回调函数,使用WINAPI就没那么明显了

 

二.消息与窗口

          1.窗口分类:

               桌面上最明显的窗口就是应用程序窗口。这些窗口含有显示程序名称的标题列、菜单甚至可能还有工具列和滚动条。

               另一类窗口是对话框,它可以有标题列也可以没有标题列。

              装饰对话框表面的还有各式各样的按键、单选按钮、复选框、清单方块、滚动条和文字输入区域。其中每一个小的视觉对象都是一个窗口。更确切地说,这些都称为「子窗口」或「控件窗口」或「子窗口控件」。

 

           2.windows给程序发送消息

                当窗口发生改变时,比如调整了窗口的大小,窗口文本改变等,windows感应这一消息,把这个消息发送给到程序的消息队列中(该消息对列用来存放该程序可能创建的各种不同窗口的消息),应用程序从消息队列中取出这条消息,然后经过转换,重新发给windows系统,系统调用相应的一个窗口过程(父窗口调用父窗口窗口过程,子窗口调用子窗口处理过程),对消息进行处理。

                窗口通常是在窗口类的基础上建立的。窗口类标识了处理窗口消息的窗口过程。使用窗口类使多个窗口能够属于同一个窗口类,并使用同一个窗口过程。例如,所有Windows程序中的所有按钮均依据同一个窗口类。这个窗口类与一个处理所有按钮消息的窗口过程(位于Windows的动态链接库中)联结。在创建这些按钮的时候,都需要指定他们的父窗口(createwindow函数中有一个父窗口句柄参数,需要设置)

 

               注意:

                     有些消息是不会进入对列的

                     例如:

                          sendmessage()函数直接调用相应的窗口过程(windows不会感应)

                          updatewindow()函数会产生WM_PAINT消息,windows进行感应这消息后,也不进入队

                                        直接调用相应的窗口过程,对wm_paint消息进行处理,其它产生wm_

                                                                                                                        paint消息,则需要入队

                                                                                iddialogmessage()函数仍然会进入队列,但程序取出消息后,进行判断,若是指定的消息,则立即调用窗口过程,对消息进行

                                        处理,不需要经过转换和分发阶段

                           translateaccelerator()函数仍然会进入队列,但程序取出消息后,进行判断,若是WM_KEYDOWN货WM_SYSDEYDOWN消息,则把这消息转换为WM_COMMAND消息,然后立即调用窗口过程,对消息进行处理,不需要经过转换和分发阶段

 

            3.消息循环

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

                                            {

                                                  TranslateMessage (&msg) ;    //对消息进行些处理,比如说键盘消息,把按键消息转为字符消息

                                                   DispatchMessage (&msg) ;    //交个操作系统,由操作系统调用窗口过程,处理完后才返回

                                              }

 

 

                     注意:  DispatchMessage (&msg)

                     这条消息将MSG结够回传给windows,然后windows将消息发送给适当的窗口过程,让窗口过程进行处理,处理完后,wndproc返回到windows,此时windows还停留在dispatchmessage调用中,在结束dispatchmessage

调用的处理之后,windows返回到应用程序,并且接着从下一个GetMessage调用开始消息循环

 

 也可以使用下面的消息循环

while(1)

{

  if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))

  {

    if (msg.message == WM_QUIT) break ;

     TranslateMessage (&msg) ;

     DispatchMessage (&msg) ;

   }

   else

   {

        ..........................

    }

 

}

 

//PeekMessage有消息时返回true,无消息时返回false,最后一个参数若为PM_REMOVE,表示消息从队列中取出来处理后删除,如果想处理后不删除,则置为 PM_NOREMOVE,不管队列中有没消息,该函数立即返回

 

 

三.绘图

       1.客户区:

                    整个应用程序窗口中未被标题列、窗口边框,以及可选的菜单列、工具列、状态列和滚动条占据的部分

                 

           2.设备描述表句柄

                   当您想在一个图形输出设备(诸如屏幕或者打印机)上绘图时,您首先必须获得一个设备内容(或者DC)的句柄。将句柄传回给程序时,Windows就给了您使用设备的权限。然后您在GDI函数中将这个句柄作为一个参数,向Windows标识您想在其上进行绘图的设备

                  由于设备描述表句柄和特定的设备有关,要想获取该设备的信息,比如说屏幕的大小,像素等等,可以使用以下函数:

 

This function retrieves information about the capabilities of a specified device.

int GetDeviceCaps(
  HDC hdc, 
  int nIndex
);
 
设备描述表中默认的属性如下
 
  
 
  
 
 

 

    3.获取设备描述表句柄方法;

           3.1 在wm_paint消息中使用beginpaint获取;

                当整个窗口或者部分窗口无效时(窗口上的内容没了),产生WM_PAINT消息,该消息使用beginPaint(hwnd,&ps),产生一条插除背景的消息,然后使得整个窗口有效,可以在上面画图或者输出文本了,使得endpaint结束。使用ValdiateRect也使得窗口无效,使窗口无效后(内容没了)是否要插除背景,则由ValdiateRect函数指定,若

该函数最后一个参数为false,则windows将不会插除背景,并且调用完beginpaint后paintstruct结构的ferase将为true;否则,内容相反

                注意;在新建窗口,调用showwindow后,只是把窗口显示出来了,但此时窗口仍然无效,因为窗口上没有内容

              当窗口过程不出来WM_PAINT消息时,交给defwindowproc去处理,处理过程为

                         case WM_PAINT:

                           BeginPaint(hwnd,&ps);

                           EndPaint(hwnd,&ps);

                           return 0;

               BeginPaint和EndPaint之间没有任何其他语句,仅仅使先前无效区域变为有效

 

                           窗口有效无效是对窗口上的内容而言的,若窗口没内容就是无效窗口,有内容就是有效窗口,跟有无背景无关

                                3.2 在非wm_paint消息中

                                 使用getdc获取设备描述表句柄(客户区),使用releasedc释放句柄

                                  使用GetWindowDC(hwnd)获取整个窗口句柄(包括标题栏,菜单栏等)

                                  使用CreateDC(hdc) 获取整个屏幕的句柄

 

                   4.GDI;

                要在窗口的显示区域绘图,可以使用Windows的图形设备接口(GDI)函数。要想在客户区上绘图,写文本,必须得获取设备描述表句柄,该设备描述中保存默认的属性值;例如,对于TextOut,设备内容的属性确定了文字的颜色、文字的背景色、x坐标和y坐标映像到窗口的显示区域的方式,以及显示文字时Windows使用的字体。

         获取了设备描述表句柄就可以调用相应的GDI函数了,比如TEXTOUT输出文本,画矩形,画椭圆等

          4.1 输出文本函数:

                      drawtext

                                        textout

                                        messagebox

                   4.2.画线

                                 movetoex;line;

                                 polyline 画连续的线

                    4.3.矩形,椭圆,圆角矩形等

                                 Rectangle   画矩形

                                 Ellipse    画椭圆

                                roundRECT  圆角矩形

                      4.4.白赛尔样条

                                polybezier;

                      4.5 填充矩形

                              fillrect

                              setrect

                               

 

 注意:

           这些GDI函数使用默认的画笔,画刷,要使用自定义画笔,可以使用createpen函数,然后使用selectobject把

            这个新建的画笔装到设备描述表中,不需要使用的时候,使用deleteobject删除

            同样也可以创建画刷,然后装入设备描述表中

 

 

四.滚动条消息

         1.WM_VSCROLL和WM_HSCROLL消息

           

 

     

         LOWORD(wParam):  消息通知码

         HIWORD(wParam);  通知码为SB_THUMBPOSITION或者SB_THUMBTRACK,此值表示滚动条的位置。其它值无效

         lParam:  0 

        2.滚动条使用的函数

 

              1.setscrollrange();  //设置滚动条的范围

               2.setcrollpos();     //设置滚动条位置

               3.getscrollpos();   //获取滚动条位置

               4.setcrollinfo();    //设置滚动条的所有信息

               5.getcrollinfo();    //获取滚动条的所有信息

                6.scrollwindow();  //使得内容被滚动

 

五。按键消息

                

         wm_keydown

         wm_keyup

         wm_char

      

       wparam  ; 虚拟键码

                  //字符按键和数字的虚拟键码为assic(字符大写)

 

六。鼠标消息

     

          WM_LBUTTONDOWN

          WM_LBUTTONUP

          WM_RBUTTONDOWN

          WM_RBUTTONUP

          WM_MOVESECUCE

 

  LOWORD(lParam); 鼠标x坐标

  HIWORD(lParam);  鼠标y坐标

  wParam;  只是鼠标键和ctrl和shift的状态

             MK_LBUTTON 按下左键

             MK_MBUTTON 按下中键

             MK_RBUTTON 按下右键

             MK_SHIFT   按下shift键

             MK_CONTROL 按下ctrl键盘

 

       可以使用if(wParam & MK_SHIFT)判断是否shift键盘按下

               if(wParam & MK_LBUTTON) 判断左键按下

          等

 

 七。子窗口消息

        1.按钮,编辑框,列表框给主窗口发送WM_COMMAND消息

             LOWORD(lParam);  子窗口ID

             HIWORD(lParam);通知吗

             lParam            子窗口句柄

        2.滚动条给窗口发送WM_VSCROLL或者WM_HSCROLL消息

 

 

            LOWORD(wParam):  消息通知码

         HIWORD(wParam);  通知码为SB_THUMBPOSITION或者SB_THUMBTRACK,此值表示滚动条的位置。其它值无效

         lParam:  滚动条句柄 

 

八。菜单消息

 

当Windows准备显示一个弹出式菜单时,它给窗口消息处理程序发送一个WM_INITMENUPOPUP消息,参数如下:

wParam: 弹出式菜单句柄

LOWORD (lParam):弹出式菜单索引

HIWORD (lParam): 系统菜单为1,其它为0

 

程序也会接收到WM_MENUSELECT消息。随着使用者在菜单项中移动光标或者鼠标,程序会收到许多WM_MENUSELECT消息。这对实作那些包含对菜单项的文字描述的状态列是很有帮助的。WM_MENUSELECT的参数如下所示:

LOWORD (wParam):被选中项目:菜单ID或者弹出式菜单句柄

HIWORD (wParam):选择旗标

lParam: 包含被选中项目的菜单句柄

 

 

最重要的菜单消息是WM_COMMAND,它表示使用者已经从菜单中选中了一个被启用的菜单项。第八章中的WM_COMMAND消息也可以由子窗口控件产生。如果您碰巧为菜单和子窗口控件使用同一ID码,那么您可以通过lParam的值来区别它们,菜单项的lParam其值为0,请参见表10-1。

表10-1

 

菜单

控件

LOWORD (wParam):

菜单ID

控件ID

HIWORD (wParam):

0

通知码

lParam:

0

子窗口句柄

WM_SYSCOMMAND消息类似于WM_COMMAND消息,只是WM_SYSCOMMAND表示使用者从系统菜单中选择一个启用的菜单项:

wParam: 菜单ID

lParam: 0

 

 

 九。对话框消息

 

      模态对话框:dialogbox

                               调用enddialog后,对话框才返回;

 

     非模态对话框: createdialog

                               立即返回对话框

 

       注意:

                    不管是模态还是非模态,创建对话框的时候,同时会创建各种子窗口,会产生wm_create,wm_size,wm_paint等消息,交给各个子窗口过程处理,虽然没有写出子窗口过程,但系统会默认处理

 

         wm_command:

LOWORD(lParam);  子窗口ID

             HIWORD(lParam);通知吗

             lParam            子窗口句柄

 

          

十。句柄

 

      获取应用程序实例句柄;

                                           getwindow(HWND hwnd , GWL_HINSTANCE); 

                                        也可以使用setwindowlong(HWND hwnd , GWL_HINSTANCE)设置新的实例句柄

                                  

   该函数还有一种用法;setwindowlong(HWND hwn,GWL_USERDATA)  //使得某一个参数和特定的窗口关联

                                          getwindowlong(HWND hwn,GWL_USERDATA)  //可以获取这个参数

 

    获取控件句柄;

                              getdlgitem(HWND hDlg, int ctrlID);          

 

    获取控件ID;

                              GetDlgCtrlID(HWND cTrl)  //参数为控件句柄

 

 

   设置文本:

                   1、     通过getdlgitem获取子控件的句柄,然后调用

                           setwindowtext(参数1,参数2); //参数1为控件句柄,参数2为要设置的文本

 

                   2.  直接使用setdlgitemtext(对话框句柄,子控件id, 要设置的字符串)

 

 

   获取文本

                    1. 通过getdlgitem获取子控件的句柄,然后调用getwindowtext(控件句柄,字符串,字符串大小);

 

                     2. getdlgitemtext(对话框句柄,子控件id, 要获得的字符串,字符串大小)

                  

                       

                             

你可能感兴趣的:(windows程序设计)