Windows Mobile 编程 (Win32) - 输出文本


《Windows 程序设计》第四章主要介绍在窗口中显示文本相关知识。示例代码量很大,但实际上是一个实例不断升级的三个版本。

SysMets1:在窗口中输出文本的基本代码;

SysMets2:在上一个实例的基础上,加入纵向滚动条;

SysMets3:加入横、纵两个方向的滚动条;

这三个版本的代码使用了共同的一个SysMets.h头文件。下面是详细代码:

//SysMets.h

#define NUMLINES ((int)(sizeof sysmetrics / sizeof sysmetrics[0]))

struct
{
    int iIndex;
    TCHAR * szLabel;
    TCHAR * szDesc;
}

sysmetrics [] =
{
    SM_CMONITORS,         TEXT("SM_CMONITORS"),         TEXT("Number of monitors"),
    SM_CXBORDER,          TEXT("SM_CXBORDER"),          TEXT("Window border width"),
    SM_CYBORDER,          TEXT("SM_CYBORDER"),          TEXT("Window border height"),
    SM_CXDOUBLECLK,       TEXT("SM_CXDOUBLECLK"),       TEXT("Double click x tolerance"),
    SM_CYDOUBLECLK,       TEXT("SM_CYDOUBLECLK"),       TEXT("Double click y tolerance"),
    SM_CXEDGE,            TEXT("SM_CXEDGE"),            TEXT("3-D border width"),
    SM_CYEDGE,            TEXT("SM_CYEDGE"),            TEXT("3-D border height"),
    SM_CXFIXEDFRAME,      TEXT("SM_CXFIXEDFRAME"),      TEXT("Dialog window frame width"),
    SM_CYFIXEDFRAME,      TEXT("SM_CYFIXEDFRAME"),      TEXT("Dialog window frame height"),
    SM_CXHSCROLL,         TEXT("SM_CXHSCROLL"),         TEXT("Horizontal scroll arrow width"),
    SM_CYVSCROLL,         TEXT("SM_CYVSCROLL"),         TEXT("Vertical scroll arrow height"),
    SM_CXICON,            TEXT("SM_CXICON"),            TEXT("Icon width"),
    SM_CYICON,            TEXT("SM_CYICON"),            TEXT("Icon height"),
    SM_CXICONSPACING,     TEXT("SM_CXICONSPACING"),     TEXT("Horizontal icon spacing"),
    SM_CYICONSPACING,     TEXT("SM_CYICONSPACING"),     TEXT("Vertical icon spacing"),
    SM_CXSCREEN,          TEXT("SM_CXSCREEN"),          TEXT("Screen width in pixels"),
    SM_CYSCREEN,          TEXT("SM_CYSCREEN"),          TEXT("Screen height in pixels"),
    SM_CXSMICON,          TEXT("SM_CXSMICON"),          TEXT("Small icon width"),
    SM_CYSMICON,          TEXT("SM_CYSMICON"),          TEXT("Small icon height"),
    SM_CXVIRTUALSCREEN,   TEXT("SM_CXVIRTUALSCREEN"),   TEXT("Virtual screen width"),
    SM_CYVIRTUALSCREEN,   TEXT("SM_CYVIRTUALSCREEN"),   TEXT("Virtual screen height"),
    SM_CXVSCROLL,         TEXT("SM_CXVSCROLL"),         TEXT("Vertical scroll width"),
    SM_CYHSCROLL,         TEXT("SM_CYHSCROLL"),         TEXT("Horizontal scroll height"),
    SM_CYCAPTION,         TEXT("SM_CYCAPTION"),         TEXT("Caption bar height"),
    SM_CYMENU,            TEXT("SM_CYMENU"),            TEXT("Menu bar height"),
    SM_DEBUG,             TEXT("SM_DEBUG"),             TEXT("Debug version flag"),
    SM_SAMEDISPLAYFORMAT, TEXT("SM_SAMEDISPLAYFORMAT"), TEXT("Same color format flag"),
    SM_XVIRTUALSCREEN,    TEXT("SM_XVIRTUALSCREEN"),    TEXT("Virtual screen x origin"),
    SM_YVIRTUALSCREEN,    TEXT("SM_YVIRTUALSCREEN"),    TEXT("Virtual screen y origin"),

    SM_CXFULLSCREEN,      TEXT("SM_CXFULLSCREEN"),      TEXT("Full screen client area width"),
    SM_CYFULLSCREEN,      TEXT("SM_CYFULLSCREEN"),      TEXT("Full screen client area height"),
    SM_MOUSEPRESENT,      TEXT("SM_MOUSEPRESENT"),      TEXT("Mouse present flag")
};
// SysMets1.c

#include <windows.h>
#include "sysmets.h"

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

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
    static TCHAR szAppName[] = TEXT("SysMets1");
    HWND     hwnd;
    MSG      msg;
    WNDCLASS wc;

    // Set up the window class description
    ZeroMemory(&wc, sizeof(wc));
    wc.style         = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc   = WndProc;
    wc.hInstance     = hInstance;
    wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wc.lpszClassName = szAppName;

    if (!RegisterClass(&wc))
    {
        MessageBox(NULL, TEXT("RegisterClass() failed!"), szAppName, MB_ICONERROR);
        return 0;
    }

    hwnd = CreateWindow(szAppName,        // window class name
        TEXT("Get System Metrics No. 1"), // window caption
        WS_OVERLAPPED | WS_SYSMENU,       // window style
        CW_USEDEFAULT,                    // initial x position
        CW_USEDEFAULT,                    // initial y position
        CW_USEDEFAULT,                    // initial x size
        CW_USEDEFAULT,                    // initial y size
        NULL,                             // parent window handle
        NULL,                             // window menu handle
        hInstance,                        // program instance handle
        NULL);                            // creation parameters
    
    if (hwnd == NULL)
    {
        MessageBox(NULL, TEXT("CreateWindow() failed!"), szAppName, MB_ICONERROR);
        return 0;
    }

    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

    while(GetMessage(&msg, NULL, 0, 0) > 0)
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    static int  cxChar, cxCaps, cyChar;
    HDC         hdc;
    int         i;
    PAINTSTRUCT ps;
    TCHAR       szBuffer[10];
    TEXTMETRIC  tm;

    switch (message)
    {
    case WM_CREATE:
        hdc = GetDC(hwnd);

        GetTextMetrics(hdc, &tm);
        cxChar = tm.tmAveCharWidth;
        cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2) * cxChar / 2;
        cyChar = tm.tmHeight + tm.tmExternalLeading;

        ReleaseDC(hwnd, hdc);
        return 0;

    case WM_PAINT:
        hdc = BeginPaint(hwnd, &ps);

        for(i = 0; i < NUMLINES; i++)
        {
            ExtTextOut(hdc, 4, cyChar * i * 3, 0, NULL,
                sysmetrics[i].szLabel,
                lstrlen(sysmetrics[i].szLabel),
                NULL);

            ExtTextOut(hdc, 4, cyChar * (i * 3 + 1), 0, NULL,
                sysmetrics[i].szDesc,
                lstrlen(sysmetrics[i].szDesc),
                NULL);

            SetTextAlign(hdc, TA_RIGHT | TA_TOP);

            ExtTextOut(hdc, cxChar * 47, cyChar * (i * 3 + 1), 0, NULL,
                szBuffer,
                wsprintf(szBuffer, TEXT("%5d"), GetSystemMetrics(sysmetrics[i].iIndex)),
                NULL);

            SetTextAlign (hdc, TA_LEFT | TA_TOP) ;
        }

        EndPaint(hwnd, &ps);
        return 0;

    case WM_DESTROY:
        PostQuitMessage(0);
        return 0 ;
    }

    return DefWindowProc(hwnd, message, wParam, lParam);
}
// SysMets2.c

#include <windows.h>
#include "sysmets.h"

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

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
    static TCHAR szAppName[] = TEXT("SysMets2");
    HWND     hwnd;
    MSG      msg;
    WNDCLASS wc;

    // Set up the window class description
    ZeroMemory(&wc, sizeof(wc));
    wc.style         = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc   = WndProc;
    wc.hInstance     = hInstance;
    wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wc.lpszClassName = szAppName;

    if (!RegisterClass(&wc))
    {
        MessageBox(NULL, TEXT("RegisterClass() failed!"), szAppName, MB_ICONERROR);
        return 0;
    }

    hwnd = CreateWindow(szAppName,        // window class name
        TEXT("Get System Metrics No. 2"), // window caption
        WS_OVERLAPPED | WS_SYSMENU,       // window style
        CW_USEDEFAULT,                    // initial x position
        CW_USEDEFAULT,                    // initial y position
        CW_USEDEFAULT,                    // initial x size
        CW_USEDEFAULT,                    // initial y size
        NULL,                             // parent window handle
        NULL,                             // window menu handle
        hInstance,                        // program instance handle
        NULL);                            // creation parameters
    
    if (hwnd == NULL)
    {
        MessageBox(NULL, TEXT("CreateWindow() failed!"), szAppName, MB_ICONERROR);
        return 0;
    }

    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

    while(GetMessage(&msg, NULL, 0, 0) > 0)
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    static int  cxChar, cxCaps, cyChar, cyClient, iVscrollPos;
    HDC         hdc;
    int         i, y;
    PAINTSTRUCT ps;
    TCHAR       szBuffer[10];
    TEXTMETRIC  tm;

    switch (message)
    {
    case WM_CREATE:
        hdc = GetDC(hwnd);

        GetTextMetrics(hdc, &tm);
        cxChar = tm.tmAveCharWidth;
        cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2) * cxChar / 2;
        cyChar = tm.tmHeight + tm.tmExternalLeading;

        ReleaseDC(hwnd, hdc);

        SetScrollRange(hwnd, SB_VERT, 0, NUMLINES * 3 - 2, FALSE);
        SetScrollPos(hwnd, SB_VERT, iVscrollPos, TRUE);
        return 0;

    case WM_SIZE:
        cyClient = HIWORD(lParam);
        return 0;

    case WM_VSCROLL:
        switch(LOWORD(wParam))
        {
        case SB_LINEUP:
            iVscrollPos -= 1;
            break;

        case SB_LINEDOWN:
            iVscrollPos += 1;
            break;

        case SB_PAGEUP:
            iVscrollPos -= cyClient / cyChar;
            break;

        case SB_PAGEDOWN:
            iVscrollPos += cyClient / cyChar;
            break;

        case SB_THUMBPOSITION:
            iVscrollPos = HIWORD(wParam);
            break;

        default:
            break;
        }

        iVscrollPos = max(0, min(iVscrollPos, NUMLINES * 3 - 2));

        SCROLLINFO si;
        ZeroMemory(&si, sizeof(SCROLLINFO));
        si.cbSize = sizeof(SCROLLINFO);
        si.fMask = SIF_POS;
        if (!GetScrollInfo(hwnd, SB_HORZ, &si))
        {
            return 0;
        }

        //if (iVscrollPos != si.nPos)
        //{
            SetScrollPos(hwnd, SB_VERT, iVscrollPos, TRUE);
            InvalidateRect(hwnd, NULL, TRUE);
        //}
        return 0;

    case WM_PAINT:
        hdc = BeginPaint(hwnd, &ps);

        for(i = 0; i < NUMLINES; i++)
        {
            y = cyChar * (i - iVscrollPos);

            ExtTextOut(hdc, 4, cyChar * (i * 3 - iVscrollPos), 0, NULL,
                sysmetrics[i].szLabel,
                lstrlen(sysmetrics[i].szLabel),
                NULL);

            ExtTextOut(hdc, 4, cyChar * (i * 3 + 1 - iVscrollPos), 0, NULL,
                sysmetrics[i].szDesc,
                lstrlen(sysmetrics[i].szDesc),
                NULL);

            SetTextAlign(hdc, TA_RIGHT | TA_TOP);

            ExtTextOut(hdc, cxChar * 44, cyChar * (i * 3 + 1 - iVscrollPos), 0, NULL,
                szBuffer,
                wsprintf(szBuffer, TEXT("%5d"), GetSystemMetrics(sysmetrics[i].iIndex)),
                NULL);

            SetTextAlign (hdc, TA_LEFT | TA_TOP) ;
        }

        EndPaint(hwnd, &ps);
        return 0;

    case WM_DESTROY:
        PostQuitMessage(0);
        return 0 ;
    }

    return DefWindowProc(hwnd, message, wParam, lParam);
}
// SysMets3.c

#include <windows.h>
#include "sysmets.h"

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

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
    static TCHAR szAppName[] = TEXT("SysMets3");
    HWND     hwnd;
    MSG      msg;
    WNDCLASS wc;

    // Set up the window class description
    ZeroMemory(&wc, sizeof(wc));
    wc.style         = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc   = WndProc;
    wc.hInstance     = hInstance;
    wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wc.lpszClassName = szAppName;

    if (!RegisterClass(&wc))
    {
        MessageBox(NULL, TEXT("RegisterClass() failed!"), szAppName, MB_ICONERROR);
        return 0;
    }

    hwnd = CreateWindow(szAppName,        // window class name
        TEXT("Get System Metrics No. 3"), // window caption
        WS_OVERLAPPED | WS_SYSMENU,       // window style
        CW_USEDEFAULT,                    // initial x position
        CW_USEDEFAULT,                    // initial y position
        CW_USEDEFAULT,                    // initial x size
        CW_USEDEFAULT,                    // initial y size
        NULL,                             // parent window handle
        NULL,                             // window menu handle
        hInstance,                        // program instance handle
        NULL);                            // creation parameters
    
    if (hwnd == NULL)
    {
        MessageBox(NULL, TEXT("CreateWindow() failed!"), szAppName, MB_ICONERROR);
        return 0;
    }

    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

    while(GetMessage(&msg, NULL, 0, 0) > 0)
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    static int  cxChar, cxCaps, cyChar, cxClient, cyClient, iMaxWidth;
    HDC         hdc;
    int         i, x, y, iVertPos, iHorzPos, iPaintBeg, iPaintEnd;
    PAINTSTRUCT ps;
    SCROLLINFO  si;
    TCHAR       szBuffer[10];
    TEXTMETRIC  tm;

    switch (message)
    {
    case WM_CREATE:
        hdc = GetDC(hwnd);

        GetTextMetrics(hdc, &tm);
        cxChar = tm.tmAveCharWidth;
        cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2) * cxChar / 2;
        cyChar = tm.tmHeight + tm.tmExternalLeading;

        ReleaseDC(hwnd, hdc);

        // Save the width of the three columns
        iMaxWidth = 40 * cxChar + 22 * cxCaps;
        return 0;

    case WM_SIZE:
        cxClient = LOWORD(lParam);
        cyClient = HIWORD(lParam);

        // Set vertical scroll bar range and page size
        si.cbSize = sizeof(si);
        si.fMask  = SIF_RANGE | SIF_PAGE;
        si.nMin   = 0;
        si.nMax   = NUMLINES - 1;
        si.nPage  = cyClient / cyChar;
        SetScrollInfo(hwnd, SB_VERT, &si, TRUE);

        // Set horizontal scroll bar range and page size
        si.cbSize = sizeof(si);
        si.fMask  = SIF_RANGE | SIF_PAGE;
        si.nMin   = 0;
        si.nMax   = 2 + iMaxWidth / cxChar;
        si.nPage  = cxClient / cxChar;
        SetScrollInfo(hwnd, SB_HORZ, &si, TRUE);
        return 0;

    case WM_VSCROLL:
        // Get all the vertial scroll bar information
        si.cbSize = sizeof(si);
        si.fMask  = SIF_ALL;
        GetScrollInfo(hwnd, SB_VERT, &si);

        // Save the position for comparison later on
        iVertPos = si.nPos;

        switch(LOWORD(wParam))
        {
        case SB_TOP:
            si.nPos = si.nMin;
            break ;

        case SB_BOTTOM:
            si.nPos = si.nMax;
            break;

        case SB_LINEUP:
            si.nPos -= 1;
            break;

        case SB_LINEDOWN:
            si.nPos += 1;
            break;

        case SB_PAGEUP:
            si.nPos -= si.nPage;
            break;

        case SB_PAGEDOWN:
            si.nPos += si.nPage;
            break;

        case SB_THUMBPOSITION:
            si.nPos = si.nTrackPos;
            break;

        default:
            break;
        }

        // Set the position and then retrieve it.  Due to adjustments
        //   by Windows it may not be the same as the value set.
        si.fMask = SIF_POS;
        SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
        GetScrollInfo(hwnd, SB_VERT, &si);

        // If the position has changed, scroll the window and update it
        if (si.nPos != iVertPos)
        {
            ScrollWindowEx(hwnd, 0, cyChar * (iVertPos - si.nPos), NULL, NULL, NULL, NULL, SW_INVALIDATE);
            InvalidateRect(hwnd, NULL, TRUE);
        }
        return 0;

    case WM_HSCROLL:
        // Get all the vertial scroll bar information
        si.cbSize = sizeof(si);
        si.fMask  = SIF_ALL;

        // Save the position for comparison later on
        GetScrollInfo(hwnd, SB_HORZ, &si);
        iHorzPos = si.nPos;

        switch (LOWORD(wParam))
        {
        case SB_LINELEFT:
            si.nPos -= 1;
            break;

        case SB_LINERIGHT:
            si.nPos += 1;
            break;

        case SB_PAGELEFT:
            si.nPos -= si.nPage;
            break;

        case SB_PAGERIGHT:
            si.nPos += si.nPage;
            break;

        case SB_THUMBPOSITION:
            si.nPos = si.nTrackPos;
            break;

        default:
            break;
        }

        // Set the position and then retrieve it.  Due to adjustments
        //   by Windows it may not be the same as the value set.

        si.fMask = SIF_POS;
        SetScrollInfo(hwnd, SB_HORZ, &si, TRUE);
        GetScrollInfo(hwnd, SB_HORZ, &si);

        // If the position has changed, scroll the window 
        if (si.nPos != iHorzPos)
        {
            ScrollWindowEx(hwnd, cxChar * (iHorzPos - si.nPos), 0, NULL, NULL, NULL, NULL, SW_INVALIDATE);
            InvalidateRect(hwnd, NULL, TRUE);
        }
        return 0;

    case WM_PAINT:
        hdc = BeginPaint(hwnd, &ps);

        // Get vertical scroll bar position
        si.cbSize = sizeof(si);
        si.fMask  = SIF_POS;
        GetScrollInfo(hwnd, SB_VERT, &si);
        iVertPos = si.nPos;

        // Get horizontal scroll bar position
        GetScrollInfo(hwnd, SB_HORZ, &si);
        iHorzPos = si.nPos;

        // Find painting limits
        iPaintBeg = max(0, iVertPos + ps.rcPaint.top / cyChar);
        iPaintEnd = min(NUMLINES - 1, iVertPos + ps.rcPaint.bottom / cyChar);

        for(i = iPaintBeg; i < iPaintEnd; i++)
        {
            x = cxChar * (1 - iHorzPos);
            y = cyChar * (i - iVertPos);

            ExtTextOut(hdc, x, y, 0, NULL,
                sysmetrics[i].szLabel,
                lstrlen(sysmetrics[i].szLabel),
                NULL);

            ExtTextOut(hdc, x + 22 * cxCaps, y, 0, NULL,
                sysmetrics[i].szDesc,
                lstrlen(sysmetrics[i].szDesc),
                NULL);

            SetTextAlign(hdc, TA_RIGHT | TA_TOP);

            ExtTextOut(hdc, x + 22 * cxCaps + 40 * cxChar, y, 0, NULL,
                szBuffer,
                wsprintf(szBuffer, TEXT("%5d"), GetSystemMetrics(sysmetrics[i].iIndex)),
                NULL);

            SetTextAlign (hdc, TA_LEFT | TA_TOP) ;
        }

        EndPaint(hwnd, &ps);
        return 0;

    case WM_DESTROY:
        PostQuitMessage(0);
        return 0 ;
    }

    return DefWindowProc(hwnd, message, wParam, lParam);
}

因为我是在Windows Mobile平台上实验的这些代码,所以与Windows平台稍有不同。

比如:GetSystemMetrics()函数在Windows Mobile平台上所能获得到的信息,相比Windows平台少很多;另外Windows Mobile平台不支持TextOut()和ScrollWindow()函数,需要更换为对应加强版函数ExtTextOut()和ScrollWindowEx()。

另外,还要考虑到Windows Mobile设置的屏幕大小问题。

优质内容筛选与推荐>>
1、MIDlet 移动开发
2、使用Sharepoint列表数据的jQuery模板
3、控制 MediaElement(播放、暂停、停止、音量和速度)
4、javascript设置窗体的高度宽度的相关参数
5、uva 558


长按二维码向我转账

受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。

    阅读
    好看
    已推荐到看一看
    你的朋友可以在“发现”-“看一看”看到你认为好看的文章。
    已取消,“好看”想法已同步删除
    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号