MFC windows图形界面基础知识1

来源:互联网 发布:武威西安交大网络教育 编辑:程序博客网 时间:2024/05/17 04:06

第一个窗口程序

1.      每个GUI应用程序至少要创建一个窗口,成为主窗口,它作为用户与应用程序间的主界面来提供服务。

2.      程序的入口:

1)   程序实例:

int APIENTRY_tWinMain(HINSTANCE hInstance,//本模块实例句柄

                     HINSTANCE hPrevInstance,//没用

                     LPTSTR    lpCmdLine,//命令行参数

                     int       nCmdShow)//主窗口显示方式

2)   程序解释:

①  GUI应用程序的入口函数WinMain,APIENTRY是_stdcall的宏定义,说明是采用标准的windows调用方式;

②  在win32下,模块的实例句柄和模块句柄是一致的。获得当前模块句柄的方法:

hInstance = (HINSTANCE)GetModuleHandle(NULL); 函数原型:(通过模块名称获得模块句柄)HMODULE WINAPI GetModuleHandle(__in LPCTSTR lpModuleName);

③   lpCmdLine 命令行参数,是CreateProcess的第二个参数指定。

④  nCmdShow主窗口初始化显示方式, 也由CreateProcess的参数决定;

3)   MessageBox函数说明:

①   函数原型:

 intMessageBox( 

           HWND hWnd,  //窗口句柄,指定哪一个窗口将拥有要创建的消息框

           LPCTSTR lpText,//将要显示的消息

           LPCTSTR lpCaption,//对话框标题

           UINT uType//指定对话框的内容和行为

);

②  第四个参数的取值:

一.为指定消息框中的按钮:MB_OK,MB_OKCANCEL,MB_ABORTRETRYIGNORE,MB_YESNOCANCEL,MB_YESNO,MB_RETRYCANCEL,

二.为在对话框中显示一个图标,MB_ICONHAND,MB_ICONQUESTION,MB_ICONEXCLAMATION,

三.指定默认的选中图标:MB_DEFBUTTON1,2,3,4

③  函数的返回值:IDYES,IDNO,IDCANCEL,IDABORT,IDRETRY,IDIGNORE,

4)   2

3.      Windows消息驱动:

1)   如何能够知道用户在窗口上的动作呢?是OS告诉程序的。Windows不断的向应用程序发送消息。

2)       Windows中窗口函数(消息处理函数),是一个自定义的回调函数。 LRESULT CALLBACK WindowProc( HWND hwnd,UINT uMsg,WPARAMwParam,LPARAM lParam);

CALLBACK也是_stdcall,hWnd标识参数到达的窗口;uMsg参数时被命名的常量(消息ID),它指定了所发的消息。

wParam和lParam是消息的两个参数,其值取决于uMsg;

3)       两个函数说明:

 HWND hW = ::FindWindow("Notepad",NULL);

//FindWindow通过窗口类名称和窗口类标题名称查找指定的窗口。

::SendMessage(hW,WM_CLOSE,0,0);

//SendMessage 用于向窗口发送消息,直到窗口处理完这个消息才返回。函数的四个参数与WindowPRoc相对应;

4)       每个窗口都关联一个窗口函数,每当这个窗口有输入时,系统调用该函数。窗口函数处理输入然后再将控制权交给OS;

5)  2

创建窗口的过程

主程序的创建流程:

1)  注册窗口类(RegisterClassEx)

2)  创建窗口(CreateWindowEx)

3)  在桌面显示窗口(ShowWIndow)

4)  更新窗口客户区(UpdateWindow)

5)  进入无线的消息获取和消息循环;

1.      注册窗口类:

 ATOMMyRegisterClass(HINSTANCE hInstance)

{

    WNDCLASSEXwcex;

 

    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_TYPER));

    //wcex.hIcon         =LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WIN32APPLICATION1));

    wcex.hCursor      = LoadCursor(NULL, IDC_ARROW);

    //指定窗口重画客户区时使用的画刷

    wcex.hbrBackground   = (HBRUSH)(COLOR_WINDOW+1);

    //wcex.lpszMenuName  =MAKEINTRESOURCE(IDR_TYPER);//

    wcex.lpszMenuName = MAKEINTRESOURCE(IDC_WIN32APPLICATION1);//

    //指定窗口类名

    wcex.lpszClassName   = szWindowClass;

    wcex.hIconSm      =LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

    return RegisterClassEx(&wcex);

}

 

结构体说明:

typedef struct {

   UINT cbSize;//结构大小

   UINT style;//窗口风格

   WNDPROC lpfnWndProc;//窗口处理函数名

   int cbClsExtra;//窗口类结构后的附加字节数

   int cbWndExtra;//窗口事例后的附加字节数

   HINSTANCE hInstance;//本模块的实例句柄

   HICON hIcon;//左上角图标句柄

   HCURSOR hCursor;//光标句柄

   HBRUSH hbrBackground;//背景画刷的句柄

   LPCTSTR lpszMenuName;//菜单名

   LPCTSTR lpszClassName;//该窗口类的类名

   HICON hIconSm;//小图标句柄

} WNDCLASSEX, *PWNDCLASSEX;

 

RegisterClassEx这个函数惟一的参数是这个结构的地址。注册窗口类后将类名和窗口函数,类的风格和其他属性联系起来。

2.      创建窗口:

    HWNDCreateWindow(         

    LPCTSTRlpClassName,//类名

   LPCTSTR lpWindowName,//标题

   DWORD dwStyle,// 窗口风格

   int x,//坐标

   int y,

   int nWidth,

   int nHeight,

   HWND hWndParent,// 父窗口句柄

   HMENU hMenu,//菜单句柄

   HINSTANCE hInstance,//程序实例句柄

   LPVOID lpParam

);

hWnd = CreateWindow(szWindowClass,szTitle, WS_OVERLAPPEDWINDOW,

      CW_USEDEFAULT, 0,CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

3.      在桌面上显示窗口:

 ShowWindow(hWnd,nCmdShow);//第二个参数是系统传递给WinMain函数的参数。

4.      更新窗口客户区: UpdateWindow(hWnd);

5.      进入无限的消息循环:windows为每个线程维护了一个消息队列,windows自动把输入翻译成消息放在消息队列中。

::GetMessage(&msg,NULL,0,0);//从调用线程的消息队列中取出一个消息。阻塞等待;

此函数如果不取得WM_QUIT消息,则返回非零值。

::TranslateMessage(&msg);将键盘翻译为可传递的消息

::DispatchMessage(&msg);//函数分发一个消息到对应窗口的窗口函数;

6.      2

处理消息的代码:

1.      必须把所有不处理的消息交给DefWindowProc函数处理,也要把它的返回值返回给windows,否则windows就失去了与应用程序通信的途径,也就不能控制窗口的行为了。

2.      WM_PAINT消息通知应用程序客户区有一块或者全部变成无效,必须刷新。

3.      WM_PAINT消息的处理:

 hdc = BeginPaint(hWnd, &ps); //使用返回的设备环境句柄不能在客户区之外绘画。

       // TODO: 在此添加任意绘图代码...

       ::TextOut(hdc,0,0,str.c_str(),str.length());//在hdc指定的设备上输出文字;string字符串类型转换为C类型的字符串:.c_str();

    EndPaint(hWnd,&ps); //释放环境句柄,使变得不可用。

4.      设置Menu的两种方式:

1)  通过注册窗口类;

2)  WM_CREATE响应;

HMENU hMenu =::LoadMenu(::GetModuleHandle(NULL),(LPCTSTR)IDR_TYPER);

::SetMenu(hWnd,hMenu);

::SetWindowText(hWnd,"最简陋的打字程序");//设置标题;

5.      当用户点击菜单中的某一个选项时,Windows即向应用程序发送一个WM_COMMAND的消息,其中参数wParam的低字节包含了用户点击菜单的ID号。

case WM_COMMAND:

       wmId    = LOWORD(wParam);

       wmEvent= HIWORD(wParam);//取出高字节的信息;

       // 分析菜单选择:

       switch (wmId)

       {

       case IDM_EXIT:

           DestroyWindow(hWnd);

           break;

    default:

6.      SendMessage函数发送的消息并不进入消息队列等待GetMessage函数取出,而是直接交给MainWndProc函数处理,并等待MainWndProc函数返回时再返回。

7.      PostMessage函数发送消息后立即返回,不等待消息的运行结果。它是把消息投放到线程所在的消息队列。

8.      用户敲击键盘所发生的消息:

WM_KEYDOWN,WM_CHAR,WM_KEYUP,

case WM_CHAR:

       {

           str= str + char(wParam);

           ::InvalidateRect(hWnd,NULL,0);//使客户区无效,触发WM_PAINT消息

           return 0;

    }

9.      鼠标移动有WM_MOUSEMOVE,消息,还有WM_LBUTTONDOWM,WM_LBUTTONUP,等的消息。发送这些消息时,lParam包含了鼠标的位置坐标。

xPos = LOWORD(lParam);

yPos = HIWORD(lParam);

 

原创粉丝点击