为什么在MDI客户区中的Win32编辑控件不起作用?

时间:2019-07-13 18:51:12

标签: winapi controls mdi

我有一个Win32 C ++ MDI表单,顶部是一个工具栏,底部是一个状态栏,状态栏上是一个编辑控件,其余的工作区都为子窗口清除。

以下是创建编辑控件的代码:

HFONT hfDefault;
HWND hEdit;

TCHAR lpszSometext[] = L"This is the first line in this edit control "
L"This is the second line in this edit control "
L"This is the third line in this edit control ";

hEdit = CreateWindowEx(
WS_EX_CLIENTEDGE, L"EDIT",
NULL,
WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL | ES_LEFT | ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL,
0, 0, 0, 0,
hWnd,
(HMENU)IDC_MAIN_EDIT,
GetModuleHandle(NULL),
NULL);

if (hEdit == NULL)
    MessageBox(hWnd, L"Could not create edit control.", L"Error", MB_OK | MB_ICONERROR);

SendMessage(hEdit, WM_SETTEXT, 0, (LPARAM)lpszSometext);

hfDefault = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
SendMessage(hEdit, WM_SETFONT, (WPARAM)hfDefault, MAKELPARAM(FALSE, 0));

这是在主窗口回调的WM_SIZE中调整工具栏,状态栏和编辑控件大小的代码;

HWND hToolbar, hStatusbar, hEdit, hMDI;
RECT rcToolbar, rcStatusbar, rcClient;
int iToolbarHeight, iStatusbarHeight, iEditHeight, iMDIHeight;

iEditHeight = 60;

hToolbar = GetDlgItem(hWnd, IDC_MAIN_TOOL);
SendMessage(hToolbar, TB_AUTOSIZE, 0, 0);

hStatusbar = GetDlgItem(hWnd, IDC_MAIN_STATUS);
SendMessage(hStatusbar, WM_SIZE, 0, 0);

GetWindowRect(hToolbar, &rcToolbar);
iToolbarHeight = rcToolbar.bottom - rcToolbar.top;

GetWindowRect(hStatusbar, &rcStatusbar);
iStatusbarHeight = rcStatusbar.bottom - rcStatusbar.top;

GetClientRect(hWnd, &rcClient);
iMDIHeight = rcClient.bottom - iToolbarHeight - iStatusbarHeight -        iEditHeight;

hEdit = GetDlgItem(hWnd, IDC_MAIN_EDIT);
SetWindowPos(hEdit, NULL, 0, rcClient.bottom - iStatusbarHeight - iEditHeight, rcClient.right, rcClient.bottom - iStatusbarHeight, SWP_NOZORDER);

hMDI = GetDlgItem(hWnd, IDC_MAIN_MDI);
SetWindowPos(hMDI, NULL, 0, iToolbarHeight, rcClient.right, iMDIHeight, SWP_NOZORDER);

所有三个控件的创建方式都与CreateWindowEx()相同,但是在创建时放在编辑控件中的文本是不显示的,并且每当调整主窗体的大小时,编辑控件都会在MDI clint窗口上产生可怕的假象,就像编辑控件试图捕捉到工具栏底部一样。

1 个答案:

答案 0 :(得分:0)

这是一个演示@A。马尔基引用链接:MDI child window and status bar C win32 API [closed]

我正在尝试将您的代码与演示结合起来,并重现您的问题。

但是您不需要在我尝试过的代码中描述的问题,但是您可以参考此演示来查找代码中的问题。

ep:

#include <windows.h>
#include <commctrl.h> //per SBARS_SIZEGRIP e STATUSCLASSNAME

#define IDM_OPEN        100
#define IDM_EXIT        101
#define IDM_ABOUT       102
#define IDC_STATUSBAR   103
#define IDM_ARRANGE     104
#define IDM_CASCADE     105
#define IDM_TILE        106
#define IDM_CLOSEALL    107
#define IDM_CLOSE       108
#define ID_CLIENTWND    109
#define IDM_FIRSTCHILD  5000
#define IDC_MAIN_EDIT 133
#define IDC_MAIN_TOOL 134

TCHAR lpszSometext[] = "This is the first line in this edit control "
"This is the second line in this edit control "
"This is the third line in this edit control ";
const char frameClass[] = "myFrameClass";
const char clientClass[] = "mdiclient"; //funziona solo con "mdiclient"
const char childClass[] = "myChildClass";

HWND hWndStatusBar = NULL;
HWND hWndClient = NULL;
HFONT hfDefault;
HWND hEdit;
HWND hToolbar;

//STEP 5 Window Procedure
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
    switch (msg) {
    case WM_CREATE:
    {
        //STEP 6: Create Status Bar
        hWndStatusBar = CreateWindowEx(0, STATUSCLASSNAME, NULL,
            WS_CHILD | WS_VISIBLE | SBARS_SIZEGRIP,
            0, 0, 0, 0,
            hwnd,
            (HMENU)IDC_STATUSBAR,
            (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), NULL);

        if (!hWndStatusBar) {
            MessageBox(NULL, "Failed To Create The Status Bar", "Error", MB_OK | MB_ICONERROR);
            return 0;
        }
        // Establish the number of partitions or 'parts' the status bar will 
        // have, their actual dimensions will be set in the parent window's 
        // WM_SIZE handler.
        RECT rc;
        GetClientRect(hwnd, &rc);
        int nHalf = rc.right / 2;
        int nParts[4] = { nHalf, nHalf + nHalf / 3, nHalf + nHalf * 2 / 3, -1 };
        SendMessage(hWndStatusBar, SB_SETPARTS, 4, (LPARAM)&nParts);

        //crea la finestra CLIENT
        CLIENTCREATESTRUCT ccs;
        // Assign the 'Window' menu.
        ccs.hWindowMenu = GetSubMenu(GetMenu(hwnd), 1); // uno perchè così la finestra appare nel secondo menu (partendo da zero) ovvero nel menu 'Windows'
        ccs.idFirstChild = IDM_FIRSTCHILD;
        // Create the client window. (quella che contiene i child!!)
        hWndClient = CreateWindowEx(WS_EX_CLIENTEDGE, clientClass,//FUNZIONA SOLO CON "mdiclient"
            NULL,
            WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE,
            0, 0, 0, 0,
            hwnd, (HMENU)ID_CLIENTWND/*GetMenu(hwnd)*/, GetModuleHandle(NULL), &ccs);
        if (hWndClient == NULL) {
            MessageBox(NULL, "Client Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
            return 0;
        }
        break;
    }
    case WM_SIZE:
    {
        HWND hToolbar, hEdit, hMDI;
        RECT rcToolbar, rcClient;
        int iToolbarHeight, iEditHeight, iMDIHeight;
        iEditHeight = 60;
        hToolbar = GetDlgItem(hwnd, IDC_MAIN_TOOL);
        SendMessage(hToolbar, TB_AUTOSIZE, 0, 0);
        GetWindowRect(hToolbar, &rcToolbar);
        iToolbarHeight = rcToolbar.bottom - rcToolbar.top;
        GetClientRect(hwnd, &rcClient);
        iMDIHeight = rcClient.bottom - iToolbarHeight - iEditHeight;
        //resize the parts
        RECT rc;
        GetClientRect(hwnd, &rc);
        int nHalf = rc.right / 2;
        int nParts[4] = { nHalf, nHalf + nHalf / 3, nHalf + nHalf * 2 / 3, -1 };
        SendMessage(hWndStatusBar, SB_SETPARTS, 4, (LPARAM)&nParts);
        //resize MDI
        // get client area of frame window
        RECT clientRect;
        GetClientRect(hwnd, &clientRect);
        int frame_dx = clientRect.right - clientRect.left;
        int frame_dy = clientRect.bottom - clientRect.top;
        // get client area of status bar
        RECT statusRect;
        GetClientRect(hWndStatusBar, &statusRect);
        int status_dy = statusRect.bottom - statusRect.top;
        // position the MDIClient such that it doesn't overlap with status bar
        MoveWindow(hWndClient, 0, 0, frame_dx, frame_dy - status_dy, TRUE);
        //resize the statusbar
        SendMessage(GetDlgItem(hwnd, IDC_STATUSBAR), WM_SIZE, 0, 0);
        hEdit = GetDlgItem(hwnd, IDC_MAIN_EDIT);
        SetWindowPos(hEdit, NULL, 0, rcClient.bottom - iEditHeight, rcClient.right, rcClient.bottom, SWP_NOZORDER);
        hMDI = GetDlgItem(hwnd, ID_CLIENTWND);
        SetWindowPos(hMDI, NULL, 0, iToolbarHeight, rcClient.right, iMDIHeight, SWP_NOZORDER);
        return 0; //ritorna zero altrimenti la Frame Window ridisegna il MDI client spalmandolo su tutta la client area andando sopra alla status bar
    }
    case WM_CLOSE:
        DestroyWindow(hwnd);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    case WM_COMMAND:
        if (LOWORD(wParam) == IDM_EXIT) DestroyWindow(hwnd);
        if (LOWORD(wParam) == IDM_ABOUT) MessageBox(hwnd, "ABOUT premuto", "ciao", MB_OK);
        if (LOWORD(wParam) == IDM_OPEN) {
            //apre il file...
            MDICREATESTRUCT mdicreate = { 0 };
            mdicreate.szClass = childClass;
            mdicreate.szTitle = "class_mdichild";
            mdicreate.hOwner = (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE); // <- hinstance
            mdicreate.x = CW_USEDEFAULT;
            mdicreate.y = CW_USEDEFAULT;
            mdicreate.cx = CW_USEDEFAULT;
            mdicreate.cy = CW_USEDEFAULT;
            mdicreate.style = 0;
            mdicreate.lParam = 0;
            HWND hwndChild = (HWND)SendMessage(hWndClient, WM_MDICREATE, 0, (LPARAM)(LPMDICREATESTRUCT)&mdicreate);
            if (hwndChild == NULL) {
                MessageBox(hwnd, "Impossibile creare la finestra Child", "Errore", MB_ICONERROR);
            }
        }
        break;
    default:
        //return DefWindowProc(hwnd,msg,wParam,lParam);
        return DefFrameProc(hwnd, hWndClient, msg, wParam, lParam); //per tenere conto delle finestre figlie
    }
    return DefFrameProc(hwnd, hWndClient, msg, wParam, lParam);
}

LRESULT CALLBACK ChildWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg) {
    case WM_COMMAND:

        break;
        /* All other messages (a lot of them) are processed using default procedures */
    default:
        return DefMDIChildProc(hwnd, msg, wParam, lParam);
    }
    return DefMDIChildProc(hwnd, msg, wParam, lParam);
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    WNDCLASSEX wc;
    HWND hwnd;
    MSG msg;

    //STEP 1: Registering Frame Class Window
    wc.cbSize = sizeof(WNDCLASSEX);
    wc.style = CS_HREDRAW | CS_VREDRAW;;
    wc.lpfnWndProc = WndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE + 1);//(COLOR_WINDOW);
    wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
    wc.lpszMenuName = NULL;
    wc.lpszClassName = frameClass;

    if (!RegisterClassEx(&wc)) {
        MessageBox(NULL, "Frame Window Registration Failed!", "Error!", MB_ICONEXCLAMATION);
        return 0;
    }

    //la classe CLIENT non la devo registrare?

    //STEP 1.2: Registering Child Class Window
    wc.lpfnWndProc = (WNDPROC)ChildWndProc;
    wc.hIcon = (HICON)LoadImage(0, IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_SHARED);
    wc.hIconSm = (HICON)LoadImage(hInstance, childClass, IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
    wc.hCursor = (HCURSOR)LoadImage(0, IDC_ARROW, IMAGE_CURSOR, 0, 0, LR_SHARED);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);//(COLOR_WINDOW);
    wc.lpszMenuName = NULL;
    wc.lpszClassName = childClass;

    if (!RegisterClassEx(&wc)) {
        MessageBox(NULL, "Child Window Registration Failed!", "Error!", MB_ICONEXCLAMATION);
        return 0;
    }

    //STEP 2: Creating the Window
    hwnd = CreateWindowEx(WS_EX_CLIENTEDGE,
        frameClass,
        "FrameWindow",
        WS_VISIBLE | WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
        NULL, NULL, hInstance, NULL);
    hEdit = CreateWindowEx(
        WS_EX_CLIENTEDGE, "EDIT",
        NULL,
        WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL | ES_LEFT | ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL,
        0, 0, 0, 0,
        hwnd,
        (HMENU)IDC_MAIN_EDIT,
        GetModuleHandle(NULL),
        NULL);
    if (hEdit == NULL)
        MessageBox(hwnd, "Could not create edit control.", "Error", MB_OK | MB_ICONERROR);

    SendMessage(hEdit, WM_SETTEXT, 0, (LPARAM)lpszSometext);

    hfDefault = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
    SendMessage(hEdit, WM_SETFONT, (WPARAM)hfDefault, MAKELPARAM(FALSE, 0));
    hToolbar = CreateWindowEx(0, TOOLBARCLASSNAME, NULL,
        WS_CHILD | TBSTYLE_WRAPABLE, 0, 0, 0, 0,
        hwnd, (HMENU)IDC_MAIN_TOOL, GetModuleHandle(NULL), NULL);
    if (hToolbar == NULL)
        return NULL;
    if (hwnd == NULL) {
        MessageBox(NULL, "Frame Window Creation Failed!", "Error!", MB_ICONEXCLAMATION);
        return 0;
    }

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



    //STEP 3: Create Menu

    HMENU hMenu = CreateMenu(); //crea un menu vuoto

    HMENU hSubMenu; //variabile usata per aggiungere sottomenu ti tipo POPUP

    hSubMenu = CreatePopupMenu();
    AppendMenu(hSubMenu, MF_STRING, IDM_OPEN, "&Open");
    AppendMenu(hSubMenu, MF_STRING, IDM_CLOSE, "&Close");
    AppendMenu(hSubMenu, MF_SEPARATOR, 0, NULL);
    AppendMenu(hSubMenu, MF_STRING, IDM_EXIT, "&Exit");
    AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, "&File"); //aggiunge il sottomenu al menu

    hSubMenu = CreatePopupMenu();
    AppendMenu(hSubMenu, MF_STRING, IDM_ARRANGE, "Arrange");
    AppendMenu(hSubMenu, MF_STRING, IDM_CASCADE, "Cascade");
    AppendMenu(hSubMenu, MF_STRING, IDM_TILE, "Tile");
    AppendMenu(hSubMenu, MF_STRING, IDM_CLOSEALL, "Close All");
    AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, "&Windows");

    hSubMenu = CreatePopupMenu();
    AppendMenu(hSubMenu, MF_STRING, IDM_ABOUT, "&About");
    AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, "&Help");

    if (hMenu == NULL) {
        MessageBox(NULL, "Menu Creation Failed!", "Error!", MB_ICONEXCLAMATION);
        return 0;
    }

    SetMenu(hwnd, hMenu); //setta il menu sulla finestra



    //STEP 4: Message Loop
    while (GetMessage(&msg, NULL, 0, 0) > 0) {
        if (hWndClient && TranslateMDISysAccel(hWndClient, &msg)) continue; //process the predefined MDI specific accelerator keys
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}

这是结果: MDI

如果有任何疑问,请随时与我联系。我很乐意帮助您解决问题。