Windows程序设计-子窗口控件

按钮类别

Windows程序设计-子窗口控件_第1张图片

/*----------------------------------------
   BTNLOOK.C -- Button Look Program
                (c) Charles Petzold, 1998
  ----------------------------------------*/

#include 

struct
{
     int     iStyle ;
     TCHAR * szText ;
}
button[] =
{
     BS_PUSHBUTTON,      TEXT ("PUSHBUTTON"),
     BS_DEFPUSHBUTTON,   TEXT ("DEFPUSHBUTTON"),
     BS_CHECKBOX,        TEXT ("CHECKBOX"), 
     BS_AUTOCHECKBOX,    TEXT ("AUTOCHECKBOX"),
     BS_RADIOBUTTON,     TEXT ("RADIOBUTTON"),
     BS_3STATE,          TEXT ("3STATE"),
     BS_AUTO3STATE,      TEXT ("AUTO3STATE"),
     BS_GROUPBOX,        TEXT ("GROUPBOX"),
     BS_AUTORADIOBUTTON, TEXT ("AUTORADIO"),
     BS_OWNERDRAW,       TEXT ("OWNERDRAW")
} ;

#define NUM (sizeof button / sizeof button[0])

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

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    PSTR szCmdLine, int iCmdShow)
{
     static TCHAR szAppName[] = TEXT ("BtnLook") ;
     HWND         hwnd ;
     MSG          msg ;
     WNDCLASS     wndclass ;

     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 = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
     wndclass.lpszMenuName  = NULL ;
     wndclass.lpszClassName = szAppName ;

     if (!RegisterClass (&wndclass))
     {
          MessageBox (NULL, TEXT ("This program requires Windows NT!"),
                      szAppName, MB_ICONERROR) ;
          return 0 ;
     }

     hwnd = CreateWindow (szAppName, TEXT ("Button Look"),
                          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  hwndButton[NUM] ;
     static RECT  rect ;
     static TCHAR szTop[]    = TEXT ("message            wParam       lParam"),
                  szUnd[]    = TEXT ("_______            ______       ______"),
                  szFormat[] = TEXT ("%-16s%04X-%04X    %04X-%04X"),
                  szBuffer[50] ;
     static int   cxChar, cyChar ;
     HDC          hdc ;
     PAINTSTRUCT  ps ;
     int          i ;

     switch (message)
     {
     case WM_CREATE :
          cxChar = LOWORD (GetDialogBaseUnits ()) ;
          cyChar = HIWORD (GetDialogBaseUnits ()) ;

          for (i = 0 ; i < NUM ; i++)
               hwndButton[i] = CreateWindow ( TEXT("button"), 
                                   button[i].szText,
                                   WS_CHILD | WS_VISIBLE | button[i].iStyle,
                                   cxChar, cyChar * (1 + 2 * i),
                                   20 * cxChar, 7 * cyChar / 4,
                                   hwnd, (HMENU) i,
                                   ((LPCREATESTRUCT) lParam)->hInstance, NULL) ;
          return 0 ;

     case WM_SIZE :
          rect.left   = 24 * cxChar ;
          rect.top    =  2 * cyChar ;
          rect.right  = LOWORD (lParam) ;
          rect.bottom = HIWORD (lParam) ;
          return 0 ;

     case WM_PAINT :
          InvalidateRect (hwnd, &rect, TRUE) ;

          hdc = BeginPaint (hwnd, &ps) ;
          SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;
          SetBkMode (hdc, TRANSPARENT) ;

          TextOut (hdc, 24 * cxChar, cyChar, szTop, lstrlen (szTop)) ;
          TextOut (hdc, 24 * cxChar, cyChar, szUnd, lstrlen (szUnd)) ;

          EndPaint (hwnd, &ps) ;
          return 0 ;

     case WM_DRAWITEM :
     case WM_COMMAND :
          ScrollWindow (hwnd, 0, -cyChar, &rect, &rect) ;

          hdc = GetDC (hwnd) ;
          SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;

          TextOut (hdc, 24 * cxChar, cyChar * (rect.bottom / cyChar - 1),
                   szBuffer,
                   wsprintf (szBuffer, szFormat,
                         message == WM_DRAWITEM ? TEXT ("WM_DRAWITEM") : 
                                                  TEXT ("WM_COMMAND"),
                         HIWORD (wParam), LOWORD (wParam),
                         HIWORD (lParam), LOWORD (lParam))) ;

          ReleaseDC (hwnd, hdc) ;
          ValidateRect (hwnd, &rect) ;
          break ;

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

所有按钮窗口样式都以字母「BS」开头,它表示「按钮样式」

CreateWindow调用使用下面这些参数:

  • Class name(类别名称) TEXT ("button")
  • Window text(窗口文字) button[i].szText
  • Window style(窗口样式) WS_CHILD | WS_VISIBLE |button[i].iStyle
  • x position(x位置)
  • y position(y位置) cxChar
  • Width(宽度) cyChar * (1 + 2 * i)
  • Height(高度) 20 * xChar
  • Parent window(父窗口) 7 * yChar / 4
  • Child window ID(子窗口ID) hwnd
  • Instance handle(执行实体句柄) (HMENU) i
  • Extra parameters(附加参数) ((LPCREATESTRUCT) lParam) ->hInstance NULL
    GetDialogBaseUnits函数来获得内定字体字符的宽度和高度。这是对话框用来获得文字尺寸的函数。此函数传回一个32位的值,其中低字组表示宽度,高字组表示高度。

子窗口向父窗口发消息

用鼠标单击按钮时,子窗口控件就向其父窗口发送一个WM_COMMAND消息。BTNLOOK拦截WM_COMMAND消息并显示wParam和lParam的值,它们的含义如下:

  • LOWORD (wParam) 子窗口ID
  • HIWORD (wParam) 通知码
  • lParam 子窗口句柄

父窗口向子窗口发送消息

父窗口可以向子窗口发送以前缀WM开头的许多消息,也可以发送前缀BM表示的按钮消息

每个子窗口控件都具有一个在其兄弟中唯一的窗口句柄ID值。对于句柄和ID这两者,知道其中的一个您就可以获得另一个。如果您知道子窗口控件的窗口句柄,那么您可以用下面的叙述来获得ID:

id = GetWindowLong (hwndChild, GWL_ID) ;

前面鼠标例子中的CHECKER3程序曾用此函数(与SetWindowLong一起)来维护注册窗口类别时保留的特殊区域的数据。在建立子窗口时,Windows保留了GWL_ID标识符存取的数据。
您也可以使用:

id = GetDlgCtrlID (hwndChild) ;

虽然函数中的「Dlg」部分指的是对话框,但实际上这是一个通用的函数。知道ID和父窗口句柄,您就能获得子窗口句柄:

hwndChild = GetDlgItem (hwndParent, id) ;

案件

仿真按钮闪动

SendMessage (hwndButton, BM_SETSTATE, 1, 0) ;
SendMessage (hwndButton, BM_SETSTATE, 0, 0) ; // 恢复正常

复选框

初始化带勾选标记的BS_CHECKBOX

SendMessage (hwndButton, BM_SETCHECK, 1, 0) ;

获取按钮状态

iCheck = (int) SendMessage (hwndButton, BM_GETCHECK, 0, 0) ;

如果该按钮被选中,则iCheck的值为TRUE或者非零数;如果按钮末被选中,则iCheck的值为FALSE或0。

单选按钮

当您收到来自单选按钮的WM_COMMAND消息时,应该向它发送wParam等于1的BM_SETCHECK消息来显示其选中状态:

SendMessage (hwndButton, BM_SETCHECK, 1, 0) ;

对同组中的其它所有单选按钮,您可以通过向它们发送wParam等于0的BM_SETCHECK消息来显示其未选中状态:

SendMessage (hwndButton, BM_SETCHECK, 0, 0) ;

分组方块

SetWindowText (hwnd, pszString) ; // 改变文字
// 获得文字
iLength = GetWindowText (hwnd, pszBuffer, iMaxLength) ;

iMaxLength指定复制到pszBuffer指向的缓冲区中的最大字符数。该函数传回复制的字符数。您可以首先通过下面的呼叫来获得特定文字的长度:

iLength = GetWindowTextLength (hwnd) ;

可见的和启用的按钮

// 没有将WS_VISIBLE包含在窗口类别中,就这样显示
ShowWindow (hwndChild, SW_SHOWNORMAL);
ShowWindow (hwndChild, SW_HIDE) ; // 隐藏
IsWindowVisible (hwndChild) ; // 获取状态
EnableWindow (hwndChild, FALSE) ; // 禁用
EnableWindow (hwndChild, TRUE) ; // 启用
IsWindowEnabled (hwndChild) ;  // 启用状态

按钮和输入焦点

父窗口可以阻止子窗口控件获得输入焦点。

case WM_KILLFOCUS :
if (hwnd == GetParent ((HWND) wParam))
SetFocus (hwnd) ;
return 0 ;

控件与颜色

使用SetTextColor和SetBkColor将文字和文字背景的颜色改变为系统颜色

SetBkColor (hdc, GetSysColor (COLOR_BTNFACE)) ;
SetTextColor (hdc, GetSysColor (COLOR_WINDOWTEXT)) ;

这样显示区域背景、文字背景和文字的颜色都与按钮的颜色一致了。但是,如果当您的程序执行时,使用者改变了系统颜色,您可能要改变文字背景颜色和文字颜色。这时您可以使用下面的程序代码:

case WM_SYSCOLORCHANGE:
InvalidateRect (hwnd, NULL, TRUE) ;
break ;

当子窗口即将为其显示区域着色时,由按钮控件发送给其父窗口消息处理程序的一个消息:WM_CTLCOLORBTN消息。父窗口可以利用这个机会来改变子窗口消息处理程序将用来着色的颜色。

当父窗口消息处理程序收到WM_CTLCOLORBTN消息时,wParam消息参数是按钮的设备内容句柄,lParam是按钮的窗口句柄。当父窗口消息处理程序得到这个消息时,按钮控件已经获得了它的设备内容。当您的窗口消息处理程序处理一个WM_CTLCOLORBTN消息
时,您必须完成以下三个动作:

  • 使用SetTextColor选择设定一种文字颜色。
  • 使用SetBkColor选择设定一种文字背景颜色。
  • 将一个画刷句柄传回给子窗口。

拥有者绘制按钮

Windows程序设计-子窗口控件_第2张图片

/*------------------------------------------------------------------------
OWNDRAW.C -- Owner-Draw Button Demo Program
(c) Charles Petzold, 1996
-------------------------------------------------------------------------*/
#include 
#define ID_SMALLER 1
#define ID_LARGER 2
#define BTN_WIDTH ( 8 * cxChar)
#define BTN_HEIGHT ( 4 * cyChar)
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
HINSTANCE hInst;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    PSTR szCmdLine, int iCmdShow)
{
    static TCHAR szAppName[] = TEXT("OwnDraw");
    MSG msg;
    HWND hwnd;
    WNDCLASS wndclass;
    hInst = hInstance;
    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 = (HBRUSH)GetStockObject
        (WHITE_BRUSH);
    wndclass.lpszMenuName = szAppName;
    wndclass.lpszClassName = szAppName;
    if (!RegisterClass(&wndclass))
    {
        MessageBox(NULL, TEXT("This program requires Windows NT!"),
            szAppName, MB_ICONERROR);
        return 0;
    }
    hwnd = CreateWindow(szAppName, TEXT("Owner-Draw Button Demo"),
        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;
}
void Triangle(HDC hdc, POINT pt[])
{
    SelectObject(hdc, GetStockObject(BLACK_BRUSH));
    Polygon(hdc, pt, 3);
    SelectObject(hdc, GetStockObject(WHITE_BRUSH));
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM
    wParam, LPARAM lParam)
{
    static HWND hwndSmaller, hwndLarger;
    static int cxClient, cyClient, cxChar,
        cyChar;
    int cx, cy;
    LPDRAWITEMSTRUCT pdis;
    POINT pt[3];
    RECT rc;
    switch (message)
    {
    case WM_CREATE:
        cxChar = LOWORD(GetDialogBaseUnits());
        cyChar = HIWORD(GetDialogBaseUnits());
        // Create the owner-draw pushbuttons
        hwndSmaller = CreateWindow(TEXT("button"), TEXT(""),
            WS_CHILD | WS_VISIBLE | BS_OWNERDRAW,
            0, 0, BTN_WIDTH, BTN_HEIGHT,
            hwnd, (HMENU)ID_SMALLER, hInst, NULL);
        hwndLarger = CreateWindow(TEXT("button"), TEXT(""),
            WS_CHILD | WS_VISIBLE | BS_OWNERDRAW,
            0, 0, BTN_WIDTH, BTN_HEIGHT,
            hwnd, (HMENU)ID_LARGER, hInst, NULL);
        return 0;
    case WM_SIZE:
        cxClient = LOWORD(lParam);
        cyClient = HIWORD(lParam);
        // Move the buttons to the new center
        MoveWindow(hwndSmaller, cxClient / 2 - 3 *
            BTN_WIDTH / 2,
            cyClient / 2 - BTN_HEIGHT / 2,
            BTN_WIDTH, BTN_HEIGHT, TRUE);
        MoveWindow(hwndLarger, cxClient / 2 + BTN_WIDTH /
            2, cyClient / 2 - BTN_HEIGHT / 2,
            BTN_WIDTH, BTN_HEIGHT,
            TRUE);
        return 0;
    case WM_COMMAND:
        GetWindowRect(hwnd, &rc);
        // Make the window 10% smaller or larger
        switch (wParam)
        {
        case ID_SMALLER:
            rc.left += cxClient / 20;
            rc.right -= cxClient / 20;
            rc.top += cyClient / 20;
            rc.bottom -= cyClient / 20;
            break;
        case ID_LARGER:
            rc.left -= cxClient / 20;
            rc.right += cxClient / 20;
            rc.top -= cyClient / 20;
            rc.bottom += cyClient / 20;
            break;
        }
        MoveWindow(hwnd, rc.left, rc.top, rc.right - rc.left,
            rc.bottom - rc.top, TRUE);
        return 0;
    case WM_DRAWITEM:
        pdis = (LPDRAWITEMSTRUCT)lParam;
        // Fill area with white and frame it black
            FillRect(pdis->hDC, &pdis->rcItem,
                (HBRUSH)GetStockObject(WHITE_BRUSH));
        FrameRect(pdis->hDC, &pdis->rcItem,
            (HBRUSH)GetStockObject
            (BLACK_BRUSH));
        // Draw inward and outward black triangles
            cx = pdis->rcItem.right - pdis->rcItem.left;
        cy = pdis->rcItem.bottom - pdis->rcItem.top;
        switch (pdis->CtlID)
        {
        case ID_SMALLER:
            pt[0].x = 3 * cx / 8; pt[0].y = 1 * cy / 8;
            pt[1].x = 5 * cx / 8; pt[1].y = 1 * cy / 8;
            pt[2].x = 4 * cx / 8; pt[2].y = 3 * cy / 8;
            Triangle(pdis->hDC, pt);
            pt[0].x = 7 * cx / 8; pt[0].y = 3 * cy / 8;
            pt[1].x = 7 * cx / 8; pt[1].y = 5 * cy / 8;
            pt[2].x = 5 * cx / 8; pt[2].y = 4 * cy / 8;
            Triangle(pdis->hDC, pt);
            pt[0].x = 5 * cx / 8; pt[0].y = 7 * cy / 8;
            pt[1].x = 3 * cx / 8; pt[1].y = 7 * cy / 8;
            pt[2].x = 4 * cx / 8; pt[2].y = 5 * cy / 8;
            Triangle(pdis->hDC, pt);
            pt[0].x = 1 * cx / 8; pt[0].y = 5 * cy / 8;
            pt[1].x = 1 * cx / 8; pt[1].y = 3 * cy / 8;
            pt[2].x = 3 * cx / 8; pt[2].y = 4 * cy / 8;
            Triangle(pdis->hDC, pt);
            break;
        case ID_LARGER:
            pt[0].x = 5 * cx / 8; pt[0].y = 3 * cy / 8;
            pt[1].x = 3 * cx / 8; pt[1].y = 3 * cy / 8;
            pt[2].x = 4 * cx / 8; pt[2].y = 1 * cy / 8;
            Triangle(pdis->hDC, pt);
            pt[0].x = 5 * cx / 8; pt[0].y = 5 * cy / 8;
            pt[1].x = 5 * cx / 8; pt[1].y = 3 * cy / 8;
            pt[2].x = 7 * cx / 8; pt[2].y = 4 * cy / 8;
            Triangle(pdis->hDC, pt);
            pt[0].x = 3 * cx / 8; pt[0].y = 5 * cy / 8;
            pt[1].x = 5 * cx / 8; pt[1].y = 5 * cy / 8;
            pt[2].x = 4 * cx / 8; pt[2].y = 7 * cy / 8;
            Triangle(pdis->hDC, pt);
            pt[0].x = 3 * cx / 8; pt[0].y = 3 * cy / 8;
            pt[1].x = 3 * cx / 8; pt[1].y = 5 * cy / 8;
            pt[2].x = 1 * cx / 8; pt[2].y = 4 * cy / 8;
            Triangle(pdis->hDC, pt);
            break;
        }
        // Invert the rectangle if the button is selected
        if (pdis->itemState & ODS_SELECTED)
            InvertRect(pdis->hDC,
                &pdis->rcItem);
        // Draw a focus rectangle if the button has the focus
            if (pdis->itemState & ODS_FOCUS)
            {
                pdis->rcItem.left += cx / 16;
                pdis->rcItem.top += cy / 16;
                pdis->rcItem.right -= cx / 16;
                pdis->rcItem.bottom -= cy / 16;
                DrawFocusRect(pdis->hDC,
                    &pdis->rcItem);
            }
        return 0;
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}

静态类

在CreateWindow函数中指定窗口类别为「static」,您就可以建立静态文字的子窗口控件。这些子窗口非常「文静」。它既不接收鼠标或键盘输入, 也不向父窗口发送WM_COMMAND消息。
当您在静态子窗口上移动或者按下鼠标时,这个子窗口将拦截WM_NCHITTEST消息并将HTTRANSPARENT的值传回给Windows,这将使Windows向其下层窗口,通常是它的父窗口,发送相同的WM_NCHITTEST消息。父窗口常常将该消息传递给DefWindowProc,在这里,它被转换为显示区域的鼠标消息。

滚动条

滚动条包括:窗口滚动条滚动条控件

与按钮控件(以及将在后面讨论的编辑和清单方块控件)不同,滚动条控件不向父窗口发送WM_COMMAND消息,而是像窗口滚动条那样发送WM_VSCROLL和WM_HSCROLL消息。在处理卷动消息时,您可以通过lParam参数来区分窗口滚动条与滚动条控件。对子窗口滚动条其值为0,对于滚动条控件其值为滚动条窗口句柄。对窗口滚动条和滚动条控件来说,wParam参数的高字组和低字组的含义相同。

取得滚动条的高宽:

GetSystemMetrics (SM_CYHSCROLL) ;
GetSystemMetrics (SM_CXVSCROLL) ;

对窗口滚动条,您可以使用同样的呼叫来建立滚动条控件的范围和位置:

SetScrollRange (hwndScroll, SB_CTL, iMin, iMax, bRedraw) ;
SetScrollPos (hwndScroll, SB_CTL, iPos, bRedraw) ;
SetScrollInfo (hwndScroll, SB_CTL, &si, bRedraw) ;

其区别在于:窗口滚动条将父窗口的句柄作为第一个参数,并且以SB_VERT或者SB_HORZ作为第二个参数。

Windows程序设计-子窗口控件_第3张图片

/*------------------------------------------------------------------------
COLORS1.C -- Colors Using Scroll Bars
(c) Charles Petzold, 1998
-------------------------------------------------------------------------*/
#include 
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK ScrollProc(HWND, UINT, WPARAM, LPARAM);
int idFocus;
WNDPROC OldScroll[3];
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    PSTR szCmdLine, int
    iCmdShow)
{
    static TCHAR szAppName[] = TEXT("Colors1");
    HWND hwnd;
    MSG msg;
    WNDCLASS wndclass;
    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 = CreateSolidBrush(0);
    wndclass.lpszMenuName = NULL;
    wndclass.lpszClassName = szAppName;
    if (!RegisterClass(&wndclass))
    {
        MessageBox(NULL, TEXT("This program requires Windows NT!"),
            szAppName, MB_ICONERROR);
        return 0;
    }
    hwnd = CreateWindow(szAppName, TEXT("Color Scroll"),
        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 COLORREF crPrim[3] = { RGB(255, 0, 0), RGB(0, 255, 0),
        RGB(0, 0, 255) };
    static HBRUSH hBrush[3], hBrushStatic;
    static HWND hwndScroll[3], hwndLabel[3], hwndValue[3],
        hwndRect;
    static int color[3], cyChar;
    static RECT rcColor;
    static TCHAR *szColorLabel[] = { TEXT("Red"), TEXT("Green"),
        TEXT("Blue") };
    HINSTANCE hInstance;
    int i, cxClient, cyClient;
    TCHAR szBuffer[10];
    switch (message)
    {
    case WM_CREATE:
        hInstance = (HINSTANCE)GetWindowLong(hwnd,
            GWL_HINSTANCE);
        // SS_WHITERECT样式的静态子窗口,作为三个滚动条的背景
            // 子窗口ID is 9.
            hwndRect = CreateWindow(TEXT("static"), NULL,
                WS_CHILD | WS_VISIBLE | SS_WHITERECT,
                0, 0, 0, 0,
                hwnd, (HMENU)9, hInstance, NULL);
        for (i = 0; i < 3; i++)
        {
            //  三个滚动条控件,窗口IDs 0, 1, and 2, with
            // 设置WS_TABSTOP才可以Tab切换焦点
                hwndScroll[i] = CreateWindow(TEXT("scrollbar"), NULL,
                    WS_CHILD | WS_VISIBLE |
                    WS_TABSTOP | SBS_VERT,
                    0, 0, 0, 0,
                    hwnd, (HMENU)i, hInstance, NULL);
            SetScrollRange(hwndScroll[i], SB_CTL, 0, 255,
                FALSE);
            SetScrollPos(hwndScroll[i], SB_CTL, 0, FALSE);
            // 三个颜色静态窗口:红绿蓝,ID是3,4,5
            hwndLabel[i] = CreateWindow(TEXT("static"), szColorLabel[i],
                WS_CHILD | WS_VISIBLE | SS_CENTER,
                0, 0, 0, 0,
                hwnd, (HMENU)(i + 3),
                hInstance, NULL);
            // 三个色值文本静态子窗口 IDs 6, 7,
            // and 8, and initial text strings of "0".
            hwndValue[i] = CreateWindow(TEXT("static"), TEXT("0"),
                WS_CHILD | WS_VISIBLE | SS_CENTER,
                0, 0, 0, 0,
                hwnd, (HMENU)(i + 6),
                hInstance, NULL);
            // 通过GWL_WNDPROC参数,设置新的窗口消息处理程序(窗口子类化)
            // 这样可以挂钩
            OldScroll[i] = (WNDPROC)SetWindowLong
                (hwndScroll[i],
                    GWL_WNDPROC, (LONG)ScrollProc);
            // 定义画刷
            hBrush[i] = CreateSolidBrush(crPrim[i]);
        }
        hBrushStatic = CreateSolidBrush(
            GetSysColor(COLOR_BTNHIGHLIGHT));
        cyChar = HIWORD(GetDialogBaseUnits());
        return 0;
    case WM_SIZE:
        cxClient = LOWORD(lParam);
        cyClient = HIWORD(lParam);
        SetRect(&rcColor, cxClient / 2, 0, cxClient, cyClient);
        MoveWindow(hwndRect, 0, 0, cxClient / 2, cyClient, TRUE);
        for (i = 0; i < 3; i++)
        {
            MoveWindow(hwndScroll[i],
                (2 * i + 1) * cxClient / 14, 2 * cyChar,
                cxClient / 14, cyClient - 4 * cyChar, TRUE);
            MoveWindow(hwndLabel[i],
                (4 * i + 1) * cxClient / 28, cyChar / 2, cxClient / 7, cyChar, TRUE);
                MoveWindow(hwndValue[i],
                    (4 * i + 1) * cxClient / 28,
                    cyClient - 3 * cyChar / 2,
                    cxClient / 7, cyChar, TRUE);
        }
        SetFocus(hwnd);
        return 0;
    case WM_SETFOCUS:
        SetFocus(hwndScroll[idFocus]);
        return 0;
    case WM_VSCROLL:
        // 获得子窗口ID
        i = GetWindowLong((HWND)lParam, GWL_ID);
        switch (LOWORD(wParam))
        {
        case SB_PAGEDOWN:
            color[i] += 15;
            // fall through
        case SB_LINEDOWN:
            color[i] = min(255, color[i] + 1);
            break;
        case SB_PAGEUP:
            color[i] -= 15;
            // fall through
        case SB_LINEUP:
            color[i] = max(0, color[i] - 1);
            break;
        case SB_TOP:
            color[i] = 0;
            break;
        case SB_BOTTOM:
            color[i] = 255;
            break;
        case SB_THUMBPOSITION:
        case SB_THUMBTRACK:
            color[i] = HIWORD(wParam);
            break;
        default:
            break;
        }
        // 设置滚动的位置
        SetScrollPos(hwndScroll[i], SB_CTL, color[i], TRUE);
        // 设置底部文字
        wsprintf(szBuffer, TEXT("%i"), color[i]);
        SetWindowText(hwndValue[i], szBuffer);
        DeleteObject((HBRUSH)
            SetClassLong(hwnd,
                GCL_HBRBACKGROUND, (LONG)
                CreateSolidBrush(RGB(color[0], color[1], color[2]))));
        // 无效窗口,强制刷新
        InvalidateRect(hwnd, &rcColor, TRUE);
        return 0;
    case WM_CTLCOLORSCROLLBAR:
        i = GetWindowLong((HWND)lParam, GWL_ID);
        return (LRESULT)hBrush[i];
    case WM_CTLCOLORSTATIC:
        i = GetWindowLong((HWND)lParam, GWL_ID);
        if (i >= 3 && i <= 8) // static text controls
        {
            SetTextColor((HDC)wParam, crPrim[i % 3]);
            SetBkColor((HDC)wParam, GetSysColor
                (COLOR_BTNHIGHLIGHT));
            return (LRESULT)hBrushStatic;
        }
        break;
    case WM_SYSCOLORCHANGE:
        DeleteObject(hBrushStatic);
        hBrushStatic = CreateSolidBrush
            (GetSysColor(COLOR_BTNHIGHLIGHT));
        return 0;
    case WM_DESTROY:
        // 清除画刷。SetClassLong设置画刷,并返回旧画刷
        DeleteObject((HBRUSH)
            SetClassLong(hwnd,
                GCL_HBRBACKGROUND, (LONG)
                GetStockObject(WHITE_BRUSH)));
        for (i = 0; i < 3; i++)
            DeleteObject(hBrush[i]);
        DeleteObject(hBrushStatic);
        PostQuitMessage(0);
        return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
LRESULT CALLBACK ScrollProc(HWND hwnd, UINT message,
    WPARAM wParam, LPARAM lParam)
{
    int id = GetWindowLong(hwnd, GWL_ID);
    switch (message)
    {
    case WM_KEYDOWN:
        if (wParam == VK_TAB)
            // 设置输入焦点
            SetFocus(GetDlgItem(GetParent
                (hwnd),
                (id + (GetKeyState(VK_SHIFT) < 0 ? 2 : 1)) % 3));
        break;
    case WM_SETFOCUS:
        idFocus = id;
        break;
    }
    return CallWindowProc(OldScroll[id], hwnd, message,
        wParam, lParam);
}

编辑类

Windows程序设计-子窗口控件_第4张图片

/*---------------------------------------------------------------------------
POPPAD1.C -- Popup Editor using child window edit box
(c) Charles Petzold, 1998
---------------------------------------------------------------------------*/
#include 
#define ID_EDIT 1
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
TCHAR szAppName[] = TEXT("PopPad1");
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
    HWND hwnd;
    MSG msg;
    WNDCLASS wndclass;
    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 = (HBRUSH)
        GetStockObject(WHITE_BRUSH);
    wndclass.lpszMenuName = NULL;
    wndclass.lpszClassName = szAppName;
    if (!RegisterClass(&wndclass))
    {
        MessageBox(NULL, TEXT("This program requires Windows NT!"),
            szAppName, MB_ICONERROR);
        return 0;
    }
    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 hwndEdit;
    switch (message)
    {
    case WM_CREATE:
        // 创建多行文本编辑器 ES_前缀定义编辑器样式
        // ES_MULTILINE 多行
        // ES_AUTOHSCROLL 自动水平滚动
        // ES_NOHIDESEL 没有输入焦点时被选择的文字仍然被加亮
        hwndEdit = CreateWindow(TEXT("edit"), NULL,
            WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL |
            WS_BORDER | ES_LEFT | ES_MULTILINE |
            ES_AUTOHSCROLL | ES_AUTOVSCROLL,
            0, 0, 0, 0, hwnd, (HMENU)ID_EDIT,
            ((LPCREATESTRUCT)lParam)->hInstance, NULL);
        return 0;
    case WM_SETFOCUS:
        SetFocus(hwndEdit);
        return 0;
    case WM_SIZE:
        // 编辑控件的尺寸
        MoveWindow(hwndEdit, 0, 0, LOWORD(lParam), HIWORD(lParam),
            TRUE);
        return 0;
    case WM_COMMAND:
        if (LOWORD(wParam) == ID_EDIT)
            if (HIWORD(wParam) == EN_ERRSPACE ||
                HIWORD(wParam) == EN_MAXTEXT)
                MessageBox(hwnd, TEXT("Edit control out of space."),
                    szAppName, MB_OK | MB_ICONSTOP);
        return 0;
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hwnd, message, wParam, lParam);
}

列表框类

列出环境变量

Windows程序设计-子窗口控件_第5张图片

/*----------------------------------------
   ENVIRON.C -- Environment List Box
                (c) Charles Petzold, 1998
  ----------------------------------------*/

#include 

#define ID_LIST     1
#define ID_TEXT     2

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

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    PSTR szCmdLine, int iCmdShow)
{
     static TCHAR szAppName[] = TEXT ("Environ") ;
     HWND         hwnd ;
     MSG          msg ;
     WNDCLASS     wndclass ;

     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 = (HBRUSH) (COLOR_WINDOW + 1) ;
     wndclass.lpszMenuName  = NULL ;
     wndclass.lpszClassName = szAppName ;

     if (!RegisterClass (&wndclass))
     {
          MessageBox (NULL, TEXT ("This program requires Windows NT!"),
                      szAppName, MB_ICONERROR) ;
          return 0 ;
     }

     hwnd = CreateWindow (szAppName, TEXT ("Environment List Box"),
                          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 ;
}

void FillListBox (HWND hwndList) 
{
     int     iLength ;
     TCHAR * pVarBlock, * pVarBeg, * pVarEnd, * pVarName ;

     pVarBlock = GetEnvironmentStrings () ;  // Get pointer to environment block

     while (*pVarBlock)
     {
          if (*pVarBlock != '=')   // Skip variable names beginning with '='
          {
               pVarBeg = pVarBlock ;              // Beginning of variable name
               while (*pVarBlock++ != '=') ;      // Scan until '='
               pVarEnd = pVarBlock - 1 ;          // Points to '=' sign
               iLength = pVarEnd - pVarBeg ;      // Length of variable name

                    // Allocate memory for the variable name and terminating
                    // zero. Copy the variable name and append a zero.

               pVarName = calloc (iLength + 1, sizeof (TCHAR)) ;
               CopyMemory (pVarName, pVarBeg, iLength * sizeof (TCHAR)) ;
               pVarName[iLength] = '\0' ;

                    // Put the variable name in the list box and free memory.

               SendMessage (hwndList, LB_ADDSTRING, 0, (LPARAM) pVarName) ;
               free (pVarName) ;
          }
          while (*pVarBlock++ != '\0') ;     // Scan until terminating zero
     }
     FreeEnvironmentStrings (pVarBlock) ;
}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
     static HWND  hwndList, hwndText ;
     int          iIndex, iLength, cxChar, cyChar ;
     TCHAR      * pVarName, * pVarValue ;

     switch (message)
     {
     case WM_CREATE :
          cxChar = LOWORD (GetDialogBaseUnits ()) ;
          cyChar = HIWORD (GetDialogBaseUnits ()) ;

               // Create listbox and static text windows.

          hwndList = CreateWindow (TEXT ("listbox"), NULL,
                              WS_CHILD | WS_VISIBLE | LBS_STANDARD,
                              cxChar, cyChar * 3,
                              cxChar * 16 + GetSystemMetrics (SM_CXVSCROLL),
                              cyChar * 5,
                              hwnd, (HMENU) ID_LIST,
                              (HINSTANCE) GetWindowLong (hwnd, GWL_HINSTANCE),
                              NULL) ;

          hwndText = CreateWindow (TEXT ("static"), NULL,
                              WS_CHILD | WS_VISIBLE | SS_LEFT,
                              cxChar, cyChar, 
                              GetSystemMetrics (SM_CXSCREEN), cyChar,
                              hwnd, (HMENU) ID_TEXT,
                              (HINSTANCE) GetWindowLong (hwnd, GWL_HINSTANCE),
                              NULL) ;

          FillListBox (hwndList) ;
          return 0 ;

     case WM_SETFOCUS :
          SetFocus (hwndList) ;
          return 0 ;

     case WM_COMMAND :
          if (LOWORD (wParam) == ID_LIST && HIWORD (wParam) == LBN_SELCHANGE)
          {
                    // Get current selection.

               iIndex  = SendMessage (hwndList, LB_GETCURSEL, 0, 0) ;
               iLength = SendMessage (hwndList, LB_GETTEXTLEN, iIndex, 0) + 1 ;
               pVarName = calloc (iLength, sizeof (TCHAR)) ;
               SendMessage (hwndList, LB_GETTEXT, iIndex, (LPARAM) pVarName) ;

                    // Get environment string.

               iLength = GetEnvironmentVariable (pVarName, NULL, 0) ;
               pVarValue = calloc (iLength, sizeof (TCHAR)) ;
               GetEnvironmentVariable (pVarName, pVarValue, iLength) ;

                    // Show it in window.

               SetWindowText (hwndText, pVarValue) ;
               free (pVarName) ;
               free (pVarValue) ;
          }
          return 0 ;

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

列出文件

Windows程序设计-子窗口控件_第6张图片

/*---------------------------------------------
   HEAD.C -- Displays beginning (head) of file
             (c) Charles Petzold, 1998
  ---------------------------------------------*/

#include 

#define ID_LIST     1
#define ID_TEXT     2

#define MAXREAD     8192
#define DIRATTR     (DDL_READWRITE | DDL_READONLY | DDL_HIDDEN | DDL_SYSTEM | \
                     DDL_DIRECTORY | DDL_ARCHIVE  | DDL_DRIVES)
#define DTFLAGS     (DT_WORDBREAK | DT_EXPANDTABS | DT_NOCLIP | DT_NOPREFIX)

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

WNDPROC OldList ;

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    PSTR szCmdLine, int iCmdShow)
{
     static TCHAR szAppName[] = TEXT ("head") ;
     HWND         hwnd ;
     MSG          msg ;
     WNDCLASS     wndclass ;

     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 = (HBRUSH) (COLOR_BTNFACE + 1) ;
     wndclass.lpszMenuName  = NULL ;
     wndclass.lpszClassName = szAppName ;

     if (!RegisterClass (&wndclass))
     {
          MessageBox (NULL, TEXT ("This program requires Windows NT!"),
                      szAppName, MB_ICONERROR) ;
          return 0 ;
     }

     hwnd = CreateWindow (szAppName, TEXT ("head"),
                          WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
                          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 BOOL     bValidFile ;
     static BYTE     buffer[MAXREAD] ;
     static HWND     hwndList, hwndText ;
     static RECT     rect ;
     static TCHAR    szFile[MAX_PATH + 1] ;
     HANDLE          hFile ;
     HDC             hdc ;
     int             i, cxChar, cyChar ;
     PAINTSTRUCT     ps ;
     TCHAR           szBuffer[MAX_PATH + 1] ;

     switch (message)
     {
     case WM_CREATE :
          cxChar = LOWORD (GetDialogBaseUnits ()) ;
          cyChar = HIWORD (GetDialogBaseUnits ()) ;

          rect.left = 20 * cxChar ;
          rect.top  =  3 * cyChar ;

          hwndList = CreateWindow (TEXT ("listbox"), NULL,
                              WS_CHILDWINDOW | WS_VISIBLE | LBS_STANDARD,
                              cxChar, cyChar * 3,
                              cxChar * 13 + GetSystemMetrics (SM_CXVSCROLL),
                              cyChar * 10,
                              hwnd, (HMENU) ID_LIST,
                              (HINSTANCE) GetWindowLong (hwnd, GWL_HINSTANCE),
                              NULL) ;

          GetCurrentDirectory (MAX_PATH + 1, szBuffer) ;

          hwndText = CreateWindow (TEXT ("static"), szBuffer,
                              WS_CHILDWINDOW | WS_VISIBLE | SS_LEFT,
                              cxChar, cyChar, cxChar * MAX_PATH, cyChar,
                              hwnd, (HMENU) ID_TEXT,
                              (HINSTANCE) GetWindowLong (hwnd, GWL_HINSTANCE),
                              NULL) ;
          // 窗口子类,使用回调函数ListProc
          OldList = (WNDPROC) SetWindowLong (hwndList, GWL_WNDPROC,
                                               (LPARAM) ListProc) ;

          SendMessage (hwndList, LB_DIR, DIRATTR, (LPARAM) TEXT ("*.*")) ;
          return 0 ;

     case WM_SIZE :
          rect.right  = LOWORD (lParam) ;
          rect.bottom = HIWORD (lParam) ;
          return 0 ;

     case WM_SETFOCUS :
          SetFocus (hwndList) ;
          return 0 ;

     case WM_COMMAND :
          if (LOWORD (wParam) == ID_LIST && HIWORD (wParam) == LBN_DBLCLK)
          {
               if (LB_ERR == (i = SendMessage (hwndList, LB_GETCURSEL, 0, 0)))
                    break ;

               SendMessage (hwndList, LB_GETTEXT, i, (LPARAM) szBuffer) ;

               // 使用CreateFile来检查是目录还是文件
               if (INVALID_HANDLE_VALUE != (hFile = CreateFile (szBuffer, 
                         GENERIC_READ, FILE_SHARE_READ, NULL, 
                         OPEN_EXISTING, 0, NULL)))

               {
                    CloseHandle (hFile) ;
                    bValidFile = TRUE ;
                    lstrcpy (szFile, szBuffer) ;
                    GetCurrentDirectory (MAX_PATH + 1, szBuffer) ;

                    if (szBuffer [lstrlen (szBuffer) - 1] != '\\')
                         lstrcat (szBuffer, TEXT ("\\")) ;
                    SetWindowText (hwndText, lstrcat (szBuffer, szFile)) ;
               }
               else
               {
                    bValidFile = FALSE ;
                    szBuffer [lstrlen (szBuffer) - 1] = '\0' ;

                         // If setting the directory doesn't work, maybe it's
                         // a drive change, so try that.
                    // SetCurrentDirectory不能执行就是磁盘驱动
                    if (!SetCurrentDirectory (szBuffer + 1))
                    {
                         szBuffer [3] = ':' ;
                         szBuffer [4] = '\0' ;
                         // 如果是磁盘驱动,则要去掉开头斜线,并加上一个冒号
                         SetCurrentDirectory (szBuffer + 2) ;
                    }

                         // Get the new directory name and fill the list box.
                    // GetCurrentDirectory返回文件句柄
                    GetCurrentDirectory (MAX_PATH + 1, szBuffer) ;
                    SetWindowText (hwndText, szBuffer) ;
                    SendMessage (hwndList, LB_RESETCONTENT, 0, 0) ;
                    SendMessage (hwndList, LB_DIR, DIRATTR, 
                                           (LPARAM) TEXT ("*.*")) ;
               }
               InvalidateRect (hwnd, NULL, TRUE) ;
          }
          return 0 ;

     case WM_PAINT :
          if (!bValidFile)
               break ;

          if (INVALID_HANDLE_VALUE == (hFile = CreateFile (szFile, GENERIC_READ, 
                    FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL)))
          {
               bValidFile = FALSE ;
               break ;
          }

          ReadFile (hFile, buffer, MAXREAD, &i, NULL) ;
          CloseHandle (hFile) ;

               // i now equals the number of bytes in buffer.
               // Commence getting a device context for displaying text.

          hdc = BeginPaint (hwnd, &ps) ;
          SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;
          SetTextColor (hdc, GetSysColor (COLOR_BTNTEXT)) ;
          SetBkColor   (hdc, GetSysColor (COLOR_BTNFACE)) ;

               // 假设文件是ASCII编码的

          DrawTextA (hdc, buffer, i, &rect, DTFLAGS) ;

          EndPaint (hwnd, &ps) ;
          return 0 ;

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

LRESULT CALLBACK ListProc (HWND hwnd, UINT message, 
                           WPARAM wParam, LPARAM lParam)
{
     if (message == WM_KEYDOWN && wParam == VK_RETURN)
          SendMessage (GetParent (hwnd), WM_COMMAND, 
                       MAKELONG (1, LBN_DBLCLK), (LPARAM) hwnd) ;

     return CallWindowProc (OldList, hwnd, message, wParam, lParam) ;
}

你可能感兴趣的:(windows,c,windows)