第一个windows程序

以下程序使用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;       //菜单
    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。这个函数名就是地址,不过取这种地址的指针在定义上与普通指针有些不同。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值