您的位置:首页 > 其它

第一个windows程序

2013-02-25 20:40 127 查看
以下程序使用vc6.0 自动生成的

主要步骤:

1、一般是先调用RegisterClassEx()函数用当前窗口句柄去向操作系统申请(或称登录)将要创建一个什么样的窗口,申请成功后;

2、再调用CreateWindowEx()函数创建一个窗口对象,这仅仅是一个外观;

3、还要调用ShowWindow()函数设置初期表示,即最大或最小或普通等;

4、最后还要调用UpdateWindow()函数向窗口传送WM_PAINT消息来画出窗口里面的内容;

5、窗口创建完后,这是一个“静止”的窗口,因此还要在WinMain()函数的最后添加消息循环,最后才return;

6、WinMain()函数完了之后,还要再编写一个“窗口消息处理”函数。

主要API:

1、ATOM RegisterClassEx ( CONST WNDCLASSEX *lpwcx );  注册窗口

      ATOM 即WORD,也就是unsigned short

2、CreateWindow()函数创建一个窗口,这儿说的窗口是广义的窗口,事实上按钮也是窗口,也是由这个函数创建的。其中最关键的是第三个参数,先看一下函数原型。

HWND CreateWindow(

    LPCTSTR lpClassName,      //窗口名

    LPCTSTR lpWindowName,     //窗口标题

    DWORD dwStyle,            //窗口式样

    int x,                    //窗口左上角的x坐标  

    int y,                    //窗口左上角的y坐标  

    int nWidth,               //窗口的宽度

    int nHeight,              //窗口的高度

    HWND hWndParent,          //父窗口句柄

    HMENU hMenu,              //菜单句柄

    HINSTANCE hInstance,      //实例句柄

    LPVOID lpParam            //创建参数

); 

窗口式样有以下几种

WS_OVERLAPPEDWINDOW

层叠式窗口,有边框、标题栏、系统菜单、最大最小化按钮,是以下几种风格的集合:WS_OVERLAPPED, WS_CAPTION, WS_SYSMENU, WS_THICKFRAME, WS_MINIMIZEBOX, WS_MAXIMIZEBOX 

WS_POPUPWINDOW

弹出式窗口,是以下几种风格的集合: WS_BORDER,WS_POPUP,WS_SYSMENU。WS_CAPTION与WS_POPUPWINDOW风格一起使用时窗口菜单才能可见

WS_OVERLAPPED   层叠式窗口,有标题栏和边框,与WS_TILED风格类似

WS_POPUP  弹出式窗口,与WS_CHILD不能同时使用

WS_BORDER  窗口有单线边框

WS_CAPTION  窗口有标题栏

WS_CHILD  子窗口,不能与WS_POPUP同时使用

WS_DISABLED  为无效窗口

WS_HSCROLL  水平滚动条

WS_ICONIC  初始化为最小化

WS_MAXIMIZE  初始化为最大化

WS_MAXIMIZEBOX  有最大化按钮

WS_MINIMIZE  与WS_MAXIMIZE一样

WS_MINIMIZEBOX  窗口有最小化按钮

WS_SIZEBOX  边框可进行大小控制的窗口

WS_SYSMENU 创建一个有系统菜单的窗口,必须与WS_CAPTION风格同时使用

WS_THICKFRAME  创建一个大小可控制的窗口,与WS_SIZEBOX风格一样.

WS_TILED  创建一个层叠式窗口,有标题栏

WS_VISIBLE  窗口为可见

WS_VSCROLL  窗口有垂直滚动条 

3、消息循环

    // Main message loop:

    while (GetMessage(&msg, NULL, 0, 0)) //GetMessage()的返回值一直不为0,直到接受WM_QUIT时才为0(也就是false)

    {

        if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))

        {

            TranslateMessage(&msg);

            DispatchMessage(&msg);//DispatchMessage()是将消息传给窗口消息处理函数

        }

    }

消息的结构体:

typedef struct {

    HWND hwnd;        //接受消息的窗口的句柄

    UINT message;     //消息(应用程序只能用低字节,高字节留给系统用)

    WPARAM wParam;    //消息的第一附加信息

    LPARAM lParam;    //消息的第二附加信息

    DWORD time;       //Specifies the time at which the message was posted.  

    POINT pt;         //Specifies the cursor position, in screen coordinates, when the message was posted.  

} MSG , *PMSG ; 

4、消息处理函数

Windows中消息的种类大致有2种,即系统消息和应用程序消息,消息的前缀也多种多样。不过日常用到的消息大都以“WM_”开头,而且许多消息的wParam和lParam都为0(也就是不使用),一般只有“WM_COMMAND”菜单命令或键盘鼠标的消息才使用wParam和lParam。

Windows中消息虽然很多,但并不是每一消息都要编程处理,我们一般把不需要特别处理的消息交给缺省消息处理函数DefWindowProc(),例子中的default部分便是。另外,有一函数必须处理,也就是关闭窗口消息WM_DESTROY,这时必须调用PostQuitMessage(0)来向操作系统发送一条终止程序的消息。 

用的最多的消息可能是WM_PAINT,当窗口改变大小、或有别的窗口从这个窗口面前经过,这个窗口中的文字或图案被冲掉,这就必须重新描画。因此,窗

口中要显示的文字或图像一般都是在WM_PAINT中实现的。下面我们以在窗口上显示一行字作例子,不过,这时要稍微知道一点GDI(Graphic Device Interface)

的知识。  

        case WM_PAINT: //重画窗口消息

            hdc = BeginPaint(hWnd, &ps);//开始描画

            // TODO: Add any drawing code here...

            RECT rt;

            GetClientRect(hWnd, &rt);//取窗口有效区域

            DrawText(hdc, szHello, strlen(szHello), &rt, DT_CENTER);//显示文字

            EndPaint(hWnd, &ps);//结束描画

            break;

// win32hello.cpp : Defines the entry point for the application.
//

#include "stdafx.h"

#include "resource.h"

#define MAX_LOADSTRING 100

// Global Variables:

HINSTANCE hInst;                                // current instance

TCHAR szTitle[MAX_LOADSTRING];                                // The title bar text

TCHAR szWindowClass[MAX_LOADSTRING];                                // The title bar text

// Foward declarations of functions included in this code module:

ATOM                MyRegisterClass(HINSTANCE hInstance);

BOOL                InitInstance(HINSTANCE, int);

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

LRESULT CALLBACK    About(HWND, UINT, WPARAM, LPARAM);

int APIENTRY WinMain(HINSTANCE hInstance,  //当前窗口实例句柄   这里的APIENTRY 即__stdcall

                     HINSTANCE hPrevInstance, //前一个实例句柄,Win32下为NULL

                     LPSTR     lpCmdLine,    //命令行参数字符

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

{

     // TODO: Place code here.

    MSG msg;

    HACCEL hAccelTable;

    // Initialize global strings

    LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);

    LoadString(hInstance, IDC_WIN32HELLO, szWindowClass, MAX_LOADSTRING);

    MyRegisterClass(hInstance); //注册窗口类

    // Perform application initialization:

    if (!InitInstance (hInstance, nCmdShow))  //初始化窗口

    {

        return FALSE;

    }

    hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_WIN32HELLO);

    // Main message loop:

    while (GetMessage(&msg, NULL, 0, 0)) //消息循环

    {

        if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))

        {

            TranslateMessage(&msg);//消息解释

            DispatchMessage(&msg);//消息发送

        }

    }

    return msg.wParam;  //注意:不能用“return 0;”,因为有非正常退出的可能性

}

//

//  FUNCTION: MyRegisterClass()

//

//  PURPOSE: Registers the window class.

//

//  COMMENTS:

//

//    This function and its usage is only necessary if you want this code

//    to be compatible with Win32 systems prior to the 'RegisterClassEx'

//    function that was added to Windows 95. It is important to call this function

//    so that the application will get 'well formed' small icons associated

//    with it.

//

ATOM MyRegisterClass(HINSTANCE hInstance) //AUTO 即WORD 也就是unsigned short

{

    WNDCLASSEX wcex;

    wcex.cbSize = sizeof(WNDCLASSEX); //这个结构体的长度,一般用sizeof(WNDCLASSEX)设置

    wcex.style            = CS_HREDRAW | CS_VREDRAW;  //窗口式样

    wcex.lpfnWndProc    = (WNDPROC)WndProc;              //窗口消息处理的函数名

    wcex.cbClsExtra        = 0;   //分配给窗口类结构之后的额外字节数,一般为0

    wcex.cbWndExtra        = 0; //分配给窗口实例之后的额外字节数,一般为0

    wcex.hInstance        = hInstance; //想要申请的窗口实例句柄

    wcex.hIcon            = LoadIcon(hInstance, (LPCTSTR)IDI_WIN32HELLO); //运行时的图标,NULL时取系统缺省图标

    wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);         //光标

    wcex.hbrBackground    = (HBRUSH)(COLOR_WINDOW+1);//背景

    wcex.lpszMenuName    = (LPCSTR)IDC_WIN32HELLO;      
c62d
//菜单

    wcex.lpszClassName    = szWindowClass;                              //窗口名

    wcex.hIconSm        = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL); //缩小时的图标,NULL时取系统缺省图标

    return RegisterClassEx(&wcex); //原型:ATOM RegisterClassEx ( CONST WNDCLASSEX *lpwcx );

}

//

//   FUNCTION: InitInstance(HANDLE, int)

//

//   PURPOSE: Saves instance handle and creates main window

//

//   COMMENTS:

//

//        In this function, we save the instance handle in a global variable and

//        create and display the main program window.

//

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{

   HWND hWnd;

   hInst = hInstance; // Store instance handle in our global variable

   hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,

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

   if (!hWnd)

   {

      return FALSE;

   }

   ShowWindow(hWnd, nCmdShow);

   UpdateWindow(hWnd);

   return TRUE;

}

//

//  FUNCTION: WndProc(HWND, unsigned, WORD, LONG)

//

//  PURPOSE:  Processes messages for the main window.

//

//  WM_COMMAND    - process the application menu

//  WM_PAINT    - Paint the main window

//  WM_DESTROY    - post a quit message and return

//

//

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)

{

    int wmId, wmEvent;

    PAINTSTRUCT ps;

    HDC hdc;

    TCHAR szHello[MAX_LOADSTRING];

    LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);

    switch (message)

    {

        case WM_COMMAND:

            wmId    = LOWORD(wParam);

            wmEvent = HIWORD(wParam);

            // Parse the menu selections:

            switch (wmId)

            {

                case IDM_ABOUT:

                   DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);

                   break;

                case IDM_EXIT:

                   DestroyWindow(hWnd);

                   break;

                default:

                   return DefWindowProc(hWnd, message, wParam, lParam); //不需要特别处理的消息

            }

            break;

        case WM_PAINT:

            hdc = BeginPaint(hWnd, &ps);

            // TODO: Add any drawing code here...

            RECT rt;

            GetClientRect(hWnd, &rt);

            DrawText(hdc, szHello, strlen(szHello), &rt, DT_CENTER);

            EndPaint(hWnd, &ps);

            break;

        case WM_DESTROY:     //必须处理的消息 关闭窗口消息

            PostQuitMessage(0); //必须调用PostQuitMessage(0)来向操作系统发送一条终止程序的消息(WM_QUIT)

            break;                         //WM_QUIT消息只能用PostMessage ,因为该消息将导致应用程序释放消息环,也就无法返回结果。

        default:

            return DefWindowProc(hWnd, message, wParam, lParam); //不需要特别处理的消息

   }

   return 0;

}

// Mesage handler for about box.

LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)

{

    switch (message)

    {

        case WM_INITDIALOG:

                return TRUE;

        case WM_COMMAND:

            if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)

            {

                EndDialog(hDlg, LOWORD(wParam));

                return TRUE;

            }

            break;

    }

    return FALSE;

}

1.  实例(instance): 这是C++的内容,“类”相当于结构体的数据类型,用“类”这种类型去定义一个变量(如果是指针,则假定已经得到了空间),这个变量就是那个“类”的“实例”。它和C语言中的变量是一回事,不过只有用“类”定义的变量才称为“实例”。  

2.  句柄(handle):这是C语言的内容,和文件句柄一样,它实际上是一个整数,用来标识是哪一个实例,也就是实例的标识符。通过句柄可以操作这个实例。  

3.  回调(CALLBACK):这其实是C语言中的函数指针,函数指针一般在大项目搭框架时常常使用。也就是你设计好要得到什么,把接口定义好,具体怎么实现完全交给别人,别人只要把函数名传给你就OK。这个函数名就是地址,不过取这种地址的指针在定义上与普通指针有些不同。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: