VC++abc之一

来源:互联网 发布:功能复古相机软件 编辑:程序博客网 时间:2024/06/04 23:24

VC++第一课

 

#include <windows.h>

#include <stdio.h>

 

LRESULT CALLBACK WinSunProc(

  HWND hwnd,      // handle to window

  UINT uMsg,      // message identifier

  WPARAM wParam,  // first message parameter

  LPARAM lParam   // second message parameter

);

//wParam lParam 为消息的附加信息,均为整型。例如按下A键,附加信息为AASCII

 

 

//主函数

int WINAPI WinMain(

  HINSTANCE hInstance,      // handle to current instance当前实例句柄 操作系统分配

  HINSTANCE hPrevInstance,  // handle to previous instance前一个实例句柄

  LPSTR lpCmdLine,          // command line命令行参数

  int nCmdShow              // show state显示状态

)

{

 

/*------------设计窗口--------------------*/

 WNDCLASS wndcls;//创建窗口类对象

 wndcls.cbClsExtra=0;//类附加字节数

 wndcls.cbWndExtra=0;//窗口附加字节数

 wndcls.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);//强制转换为画刷句柄

 

 wndcls.hCursor=LoadCursor(NULL,IDC_CROSS);//标准光标第一个参数为空  鼠标形状

 

 wndcls.hIcon=LoadIcon(NULL,IDI_ERROR);//导入图标 NULL第一个参数 标准图标。图标样式IDI_ERROR最左上的图标。

 

 wndcls.hInstance=hInstance;//当前应用程序句柄 WinMain函数的形参给其赋值。这值是由操作系统分配的实例号。

 

 wndcls.lpfnWndProc=WinSunProc;//函数名为首地址 确定回调函数。操作系统会帮助我们调用此函数但是此函数的代码需要由设计者完成

       

 wndcls.lpszClassName="Weixin2003";//窗口类名

 

 wndcls.lpszMenuName="hehe";//本应用程序没有菜单 可以设置NULL

 //菜单名

 wndcls.style=CS_HREDRAW | CS_VREDRAW;

 //窗口类型为水平竖直重绘

 

/*------------注册窗口--------------------*/

 RegisterClass(&wndcls);

 

/*------------创建窗口--------------------*/

 HWND hwnd;

 hwnd=CreateWindow("Weixin2003","北京维新科学技术培训中心",WS_OVERLAPPEDWINDOW,

  0,0,600,400,NULL,NULL,hInstance,NULL);

  /*第一个参数为要注册窗口的名字,第二个参数为窗口的标题,第三个参数为窗口类型,

    第四个参数为水平坐标,第五个窗口为竖直坐标,第六个参数为窗口的宽,第七个参数

    为窗口的高,第八个参数为父窗口句柄,第九个为菜单句柄,第十个为当前应用程序实例句柄

  */

 

/*------------显示更新窗口-----------*/

 ShowWindow(hwnd,SW_SHOWNORMAL);

 //第一个参数为所要显示窗口的句柄,第二个为显示状态

 UpdateWindow(hwnd);

 

 

 MSG msg;

 

/*BOOL GetMessage(

  LPMSG lpMsg,         // address of structure with message

  HWND hWnd,           // handle of window

  UINT wMsgFilterMin,  // first message

  UINT wMsgFilterMax   // last message

  第三个和第四个参数设置为零,则返回所有消息。

  第二个参数为空,为可以得到所有窗口的信息。

  If the function retrieves the WM_QUIT message, the return value is zero.

);*/

 

/*------------消息循环-----------*/

 while(GetMessage(&msg,NULL,0,0))//GetMessage函数是从消息队列中取得消息 每一个应用程序操作系统都会给它建立消息队列

 {

  TranslateMessage(&msg);

  //WM_KEYUP WM_KEYDOWN消息转换为WM_CHAR消息,并放入队列中。对消息进行转换。

 

  DispatchMessage(&msg);

  //分发消息给操作系统,再给回调函数处理。

  //将收到的消息传到窗口回调函数中去处理。此函数的作用是将消息路由给了操作系统然后操作系统去

  //调用窗口过程函数。

 }

 return 0;

}

 

 

 

LRESULT CALLBACK WinSunProc(//#define CALLBACK    __stdcall一种调用约定。在MSDN中输入__stdcall。使用CALLBACK语意清晰。即回调。LRESULT长整型。

  HWND hwnd,      // handle to window

  UINT uMsg,      // message identifier

  WPARAM wParam,  // first message parameter

  LPARAM lParam   // second message parameter

)//窗口处理过程,函数名可以修改,LRESULTlong类型 和消息结构体前四个参数一样

{

 switch(uMsg)

 {

 case WM_CHAR:

  char szChar[20];

  sprintf(szChar,"char is %d",wParam);

  //格式化字符串到字符数组中,wParam里面存放的是ASCII

  MessageBox(hwnd,szChar,"weixin",0);

        /*

        int MessageBox(

        HWND hWnd,          // handle of owner window

        LPCTSTR lpText,     // address of text in message box

        LPCTSTR lpCaption,  // address of title of message box

        UINT uType          // style of message box

        0MB_OK

        );

        */

  break;

 case WM_LBUTTONDOWN:

  MessageBox(hwnd,"mouse clicked","weixin",0);

  HDC hdc;

  //DC表示设备上下文 ,设备描述表 一种数据结构.DC和显卡(显示驱动程序)打交道。

  hdc=GetDC(hwnd);//设定与哪个窗口相关  作图需要一块画布 此画布为窗口

  TextOut(hdc,0,50,"计算机编程语言培训",strlen("计算机编程语言培训"));//往窗口输出文本  横坐标为0纵坐标为50的地方

  /*

  BOOL TextOut(

        HDC hdc,           // handle to device context

        int nXStart,       // x-coordinate of starting position

        int nYStart,       // y-coordinate of starting position

        LPCTSTR lpString,  // pointer to string

        int cbString       // number of characters in string

        );

        */

  ReleaseDC(hwnd,hdc);//释放资源 如忘释放则会出现内存泄漏

  break;

 case WM_PAINT://重绘??? 当窗口重绘时会发送此消息。即改变窗口尺寸时。

  HDC hDC;

  PAINTSTRUCT ps;

  hDC=BeginPaint(hwnd,&ps);//可以获取一个DC的句柄

  TextOut(hDC,0,0,"维新培训",strlen("维新培训"));

  EndPaint(hwnd,&ps);//释放DC

  //BeginPaint EndPaint只能用在WM_PAINT消息中使用  GetDCReleaseDC不能在WM_PAINT中使用只能在其他消息中使用。

  //运行程序后点击鼠标左键会出现一串文字 然后改变窗口大小时 对窗口进行了重绘 文字消失。每次重绘是重新书写。重新绘图。

  break;

 case WM_CLOSE:

  if(IDYES==MessageBox(hwnd,"是否真的结束?","weixin",MB_YESNO))//MessageBox返回值为IDYES(即点击了确定按钮)

  “是”按纽选中 if判断中把常量写在左边!!!不然很容易变成赋值!!!!

  {

   DestroyWindow(hwnd);//发送WM_DESTROY消息 Destroywindows函数销毁窗口

  }

  break;

 case WM_DESTROY://调用DestroyWindow函数后窗口已销毁   //如果点击NO窗口退出,程序运行?

//if(IDYES==MessageBox(hwnd,"是否真的结束?","weixin",MB_YESNO))

// {

  PostQuitMessage(0);//发送WM_QUIT消息

// }

  break;

 default:

  return DefWindowProc(hwnd,uMsg,wParam,lParam);//缺省处理 不感兴趣的消息交给系统处理。这个是必不可少的。

 }

 return 0;

}

 

//LPCTSTR为常量字符串

/*typedef struct tagMSG {     // msg

    HWND   hwnd;    

    UINT   message;

    WPARAM wParam;

    LPARAM lParam;

    DWORD  time;

    POINT  pt;

} MSG; */

 

回调函数的原理:

由窗口类型
typedef struct _WNDCLASS { 
    UINT    style; 
    WNDPROC lpfnWndProc; 
    int     cbClsExtra; 
    int     cbWndExtra; 
    HANDLE  hInstance; 
    HICON   hIcon; 
    HCURSOR hCursor; 
    HBRUSH  hbrBackground; 
    LPCTSTR lpszMenuName; 
    LPCTSTR lpszClassName; 
} WNDCLASS; 

中的参数lpfnWndProc来指定回调函数。本实例当中

wndcls.lpfnWndProc=WinSunProc;

//函数名为首地址 确定回调函数。操作系统会帮助我们调用此函数但是此函数的代码需要由设计者完成。回调函数的原理是:当应用程序收到给某一窗口的消息,就应该调用某一函数来处理此消息。这一调用过程不用应用程序来实施,而是由操作系统完成。但是回调函数本身的代码必须由应用程序完成,对于某一消息,操作系统到底调用哪一个函数(回调函数)呢?操作系统调用的就是接受消息的窗口属性中的lpfnWndProc所指定的函数。某一种不同类型的窗口都有自己专用的回调函数。该函数就是用lpfnWndProc来指定。

 

 

 

 

 

 

 

 

 

 

 

 

 

/*------------消息循环-----------*/

 while(GetMessage(&msg,NULL,0,0))//GetMessage函数是从消息队列中取得消息 每一个应用程序操作系统都会给它建立消息队列

 {

  TranslateMessage(&msg);

 //WM_KEYUP WM_KEYDOWN消息转换为WM_CHAR消息,并放入队列中。对消息进行转换。

 DispatchMessage(&msg);

 //分发消息给操作系统,再给回调函数处理。

//将收到的消息传到窗口回调函数中去处理。此函数的作用是将消息路由给了操作系统然后操作系统去

//调用窗口过程函数。

 }

 return 0;

}

GetMessage函数只有当取得VM_QUIT消息时候才会返回0.

当一个应用程序建立时,操作系统会为这个应用程序分配一个消息队列。凡是与我们程序相关的消息操作系统都会把这些消息放进消息队列当中。然后我们应用程序的GetMessage函数从消息队列中取出一个具体的消息利用我们的  TranslateMessage()函数将我们的按键(KEY_UP+KEY_DOWN)这样的消息转换成一个VM_CHAR消息放进消息队列当中。利用DispatchMessage()函数将此消息投递出去分发出去(可以理解为分发给了操作系统,然后操作系统利用我们在设计窗口类时所指定的窗口回调函数进行消息处理)。在此例中为WinSunProc()函数,此函数中对不同的消息进行不同的响应。这样就完成了整个消息的循环。

 

 

VM_PAINT:当窗口重绘时会发送此消息。重绘(我理解为窗口尺寸大小的改变)。

VM_CLOSE:当窗口要关闭时会发送这样一个消息。

DestroyWindow(hwnd);此函数发送WM_DESTROY消息销毁窗口。

PostQuitMessage(0);此函数通知系统线程终止。发送WM_QUIT消息当GetMessage函数取得此消息时候,white中的语句为假,终止循环退出WINMAIN函数。

 

 

LRESULT CALLBACK WinSunProc(

  HWND hwnd,      // handle to window

  UINT uMsg,      // message identifier

  WPARAM wParam,  // first message parameter

  LPARAM lParam   // second message parameter

)//窗口处理过程,函数名可以修改,LRESULTlong类型 和消息结构体前四个参数一样

CALLBACK:   #define CALLBACK   __stdcall一种调用约定。

MSDN中输入__stdcall

使用CALLBACK语意清晰,即回调。

LRESULT长整型。

窗口的创建需要经过下面四个步骤:

设计一个窗口类;(就像生产汽车前需要图纸设计)

注册窗口类;(图纸设计交给政府待批,在此政府即操作系统,操作系统一般是批准即注册成功)。

创建窗口;(政府批准后,可以按照图纸生产汽车,在此:应用程序可以按照设计的窗口类型创建窗口)。

显示及更新窗口;(维护保养)。

 

窗口过程函数:

 

举例:汽车厂家生产汽车好比应用程序创建窗口,用户使用汽车好比操作系统管理窗口,某种汽车在销售前就指定好了修理站(类似回调函数),当用户的汽车出现故障后(类似窗口收到消息),汽车用户(类似操作系统)自己直接找到修理站去修理,不用厂家(类似应用程序)亲自将车送到修理站去修理,但修理站还得由厂家事先建造好。

 

原创粉丝点击