Chinaunix首页 | 论坛 | 博客
  • 博客访问: 525389
  • 博文数量: 158
  • 博客积分: 4015
  • 博客等级: 上校
  • 技术积分: 1711
  • 用 户 组: 普通用户
  • 注册时间: 2009-01-27 14:00
文章分类

全部博文(158)

文章存档

2010年(71)

2009年(87)

我的朋友

分类: C/C++

2010-01-11 21:04:41

这个程序就非常有意思了, 教会了我们很多的东西,创建子窗口,子窗口消息处理函数, 如果你与上一篇文章比较一下, 会学到很多的东西.
代码:

#include <windows.h>
#define DIV 6

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK ChildWndProc(HWND, UINT, WPARAM, LPARAM);
int idFocus = 0;
TCHAR szChildName[] = TEXT("child windows");
int WINAPI WinMain(HINSTANCE hInstance,
                 HINSTANCE hPrevInstance,
                 PSTR szCmdLine,
                 int iCmdShow) {
    static TCHAR szAppName[] = TEXT("HIT TEST FOR CHILD WINDOWS");
    WNDCLASS wndclass;
    HWND hwnd;
    MSG msg;

    wndclass.style = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc = WndProc;
    wndclass.cbClsExtra = 0;
    wndclass.cbWndExtra = 0;
    wndclass.hInstance = hInstance;
    wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
    wndclass.hbrBackground = GetStockObject(WHITE_BRUSH);
    wndclass.lpszMenuName = NULL;
    wndclass.lpszClassName = szAppName;

    if(!RegisterClass(&wndclass)) {
        MessageBox(NULL, TEXT("Register failure..."),
            szAppName, MB_ICONERROR);
        return 0;
    }

    wndclass.lpfnWndProc = ChildWndProc;
    wndclass.cbWndExtra = 4;
    wndclass.hIcon = NULL;
    wndclass.lpszClassName = szChildName;

    RegisterClass(&wndclass);

    hwnd = CreateWindow(szAppName,
        szAppName,
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        NULL,
        NULL,
        hInstance,
        NULL);
    ShowWindow(hwnd, iCmdShow);
    UpdateWindow(hwnd);

    while(GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd,
                         UINT message,
                         WPARAM wParam,
                         LPARAM lParam) {
    static HWND hwndChild[DIV][DIV];
    static int cxBlock, cyBlock;
        int x, y;
    POINT pt;

    switch(message) {
    case WM_CREATE:
        for(x = 0; x < DIV; x++)
            for(y = 0; y < DIV; y++)
                hwndChild[x][y] = CreateWindow(szChildName,
                NULL,
                WS_CHILDWINDOW | WS_VISIBLE,
                0, 0, 0, 0,
                hwnd,
                (HMENU)(y << 8 | x),
                (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), NULL);
            return 0;

    case WM_SIZE:
        cxBlock = LOWORD(lParam) / DIV;
        cyBlock = HIWORD(lParam) / DIV;
        for(x = 0; x < DIV; x++)
            for( y = 0; y < DIV; y++)
                MoveWindow(hwndChild[x][y], x * cxBlock, y * cyBlock,
                cxBlock, cyBlock, TRUE);
            return 0;

    case WM_SETFOCUS:
        SetFocus(GetDlgItem(hwnd, idFocus));
        return 0;
    case WM_KEYDOWN:
        x = idFocus & 0xFF;
        y = idFocus >> 8;
        switch(wParam) {
        case VK_UP:
            y--;
            break;
        case VK_DOWN:
            y++;
            break;
        case VK_LEFT:
            x--;
            break;
        case VK_RIGHT:
            x++;
            break;
        case VK_HOME:
            x = 0;
            break;
        case VK_END:
            x = DIV - 1;
            break;
        default:
            break;
        }
        x = (x + DIV) % DIV;
        y = (y + DIV) % DIV;
        idFocus = y << 8 | x;
        pt.x = (x + 0.5) * cxBlock;
        pt.y = (y + 0.5) * cyBlock;
        ClientToScreen(hwnd, &pt);
        SetCursorPos(pt.x, pt.y);
        SetFocus(GetDlgItem(hwnd, idFocus));
        return 0;

        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
    }
    return DefWindowProc(hwnd, message, wParam, lParam);
}

LRESULT CALLBACK ChildWndProc(HWND hwnd,
                         UINT message,
                         WPARAM wParam,
                         LPARAM lParam) {
    static int cxClient, cyClient;
    HDC hdc;
    PAINTSTRUCT ps;
    RECT rect;
    
    switch(message) {
    case WM_CREATE:
        SetWindowLong(hwnd, 0, 0);
        return 0;
    case WM_SIZE:
        cxClient = LOWORD(lParam);
        cyClient = HIWORD(lParam);
        return 0;
    case WM_KEYDOWN:
        if(wParam == VK_SPACE) {
            SendMessage(hwnd, WM_LBUTTONDOWN, MK_LBUTTON, 0);
            InvalidateRect(hwnd, NULL, TRUE);
        }
        else
            SendMessage(GetParent(hwnd), WM_KEYDOWN, wParam, lParam);
        return 0;
    case WM_LBUTTONDOWN:
        SetWindowLong(hwnd, 0, 1 ^ GetWindowLong(hwnd, 0));
        SetFocus(hwnd);
        return 0;
    case WM_SETFOCUS:
        idFocus = GetWindowLong(hwnd, GWL_ID);
        InvalidateRect(hwnd, NULL, FALSE);
        return 0;
    case WM_KILLFOCUS:
        InvalidateRect(hwnd, NULL, TRUE);
        return 0;
    case WM_PAINT:
        hdc = BeginPaint(hwnd, &ps);
        GetClientRect(hwnd, &rect);
        Rectangle(hdc, 0, 0, rect.right, rect.bottom);
        if(GetWindowLong(hwnd, 0)) {
            MoveToEx(hdc, 0, 0, NULL);
            LineTo(hdc, cxClient, cyClient);
            MoveToEx(hdc, cxClient, 0, NULL);
            LineTo(hdc, 0, cyClient);
        }

        if(hwnd == GetFocus()) {
            rect.left = rect.right / 50;
            rect.top = rect.bottom / 30;
            rect.right -= rect.left;
            rect.bottom -= rect.top;
            SelectObject(hdc, GetStockObject(NULL_BRUSH));
            SelectObject(hdc, CreatePen(PS_DOT, 0, 0));
            Rectangle(hdc, rect.left, rect.top, rect.right, rect.bottom);
            DeleteObject(GetStockObject(BLACK_PEN));
        }
        EndPaint(hwnd, &ps);
        return 0;
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hwnd, message, wParam, lParam);
}


阅读(902) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~