Как мне создать дочернее окно в win32 при программировании на C ++? - PullRequest
1 голос
/ 08 мая 2009

Я новичок в C ++, а также для программирования Windows ..

Я создал окно, используя функцию MSDN CreateWindow()

, который работает правильно. Теперь я хотел бы создать дочернее окно ... родительское окно должно управлять дочерним окном ...

Любой помогает пример кода относительно этого.

Заранее спасибо

Ответы [ 4 ]

5 голосов
/ 08 мая 2009

Грубо говоря, в обработчике для родителя, где вы хотите создать дочернего элемента, вы вызываете CreateWindow, передавая в окне для родителя значение hwndParent - возможно, вы также хотите установить определенные стили на ребенок, такой как WS_CHILD. Ваше взаимодействие с дочерним окном зависит от типа созданного вами окна. Некоторые окна (например, кнопки) предназначены для работы в качестве дочерних окон, поэтому они отправляют множество уведомлений, поэтому вы должны настроить своего родителя на прослушивание этих уведомлений.

4 голосов
/ 08 мая 2009

Я бы настоятельно рекомендовал прочитать Чарльза Петцольда"Программирование Windows", если вы можете получить копию.

В противном случае, чтобы ответить на ваш вопрос, передайте дескриптор родительского окна в качестве родительского при создании дочернего окна (используя либо CreateWindow, либо CreateWindowEx ):

HWND CreateWindowEx
(      
    DWORD dwExStyle,
    LPCTSTR lpClassName,
    LPCTSTR lpWindowName,
    DWORD dwStyle,
    int x,
    int y,
    int nWidth,
    int nHeight,
    HWND hWndParent,      /// pass the parent window handle here
    HMENU hMenu,
    HINSTANCE hInstance,
    LPVOID lpParam
);

.. Как и в 1800 Info, возможно, также установить стиль WS_CHILD (более подробно Стиль окна здесь). Это просто рудиментарная сантехника, правда ..

Можете ли вы быть более конкретным, когда говорите "контролировать дочернее окно ..."?

1 голос
/ 16 марта 2018

Сейчас 2018 год ... выполняя ретро-работу над этим, я обнаружил, что SetParent () пригодится, чтобы убедиться, что дочернее окно остается внутри клиентской области родителя. ) ребенок не должен быть зарегистрирован как ребенок. В CreateWindowEx родительский дескриптор может сначала быть NULL. Стиль WS_CHILD не нужен, но WS_CLIPSIBLINGS удобен, он избегает мерцания.

Это мой код для создания дочернего окна:

    HWND hwnd = CreateWindowExA(0, "WindowOfDLL", ctitle, WS_SIZEBOX | WS_CLIPSIBLINGS, CW_USEDEFAULT, CW_USEDEFAULT, 400, 300, NULL, hMenu, inj_hModule, NULL);
    SetParent(hwnd, hwndparent);
    ShowWindow(hwnd, SW_SHOWNORMAL);

Я не видел проблем (пока) с многопоточностью в Win10. Каждое из нижеприведенных дочерних окон создается в DLL, которая управляет сборкой. Когда дочернее окно создано, DLL добавляет новый элемент в сборку и запускает поток, который будет обслуживать дочернее окно и выполняет вышеуказанный код при его инициализации.

parent window with WS_CLIPCHILDREN

0 голосов
/ 18 января 2019
"could you post more of your code "

@ БрэдБ, вы правы .. наши ответы не очень конкретны, это старые вещи, которые трудно поместить полный кадр в один пост. Прочитайте книгу, которую RobS предложил мне сказать ... и ... взгляните на Visual studio и более современные методы проектирования"дочерних окон", таких как Winforms, WPF и Universal!

Вот еще немного моего унаследованного кода, только подготовка, чтобы это было окно РЕБЕНКА. События и т. Д. Вы должны будете заполнить сами ..

 BOOL RegisterDLLWindowClass(LPCWSTR s)
    {
      WNDCLASSEX wc;
      wc.hInstance = NULL; // inj_hModule;
      wc.lpszClassName = s;
      wc.lpfnWndProc = DLLWindowProc;
      wc.style = CS_DBLCLKS;
      wc.cbSize = sizeof(WNDCLASSEX);
      wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
      wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
      wc.hCursor = LoadCursor(NULL, IDC_ARROW);
      wc.lpszMenuName = NULL;
      wc.cbClsExtra = 0;
      wc.cbWndExtra = 0;
      wc.hbrBackground = (HBRUSH)COLOR_BACKGROUND;
      if (!RegisterClassEx(&wc))
        return 0;
    }

    HMENU CreateDLLWindowMenu()
        {
          WriteLine("Create menu");
          HMENU hMenu;
          hMenu = CreateMenu();
          HMENU hMenuPopup;
          if (hMenu == NULL)
            return FALSE;
          hMenuPopup = CreatePopupMenu();
          AppendMenu(hMenuPopup, MF_STRING, MYMENU_FILTERSOFF, TEXT("Off"));
          AppendMenu(hMenuPopup, MF_STRING, MYMENU_CANNY, TEXT("Canny"));
          AppendMenu(hMenuPopup, MF_STRING, MYMENU_SOBEL, TEXT("Sobel"));
          AppendMenu(hMenuPopup, MF_STRING, MYMENU_THRESHOLD, TEXT("Threshold"));
          AppendMenu(hMenuPopup, MF_STRING, MYMENU_DILATE, TEXT("Dilate"));
          AppendMenu(hMenuPopup, MF_STRING, MYMENU_HARRIS, TEXT("Harris"));
          CheckMenuItem(hMenuPopup, 0, MF_BYPOSITION | MF_CHECKED);

          AppendMenuW(hMenu, MF_POPUP, (UINT_PTR)hMenuPopup, TEXT("Filter"));

          HMENU hMenuPopup2 = CreatePopupMenu();
          AppendMenu(hMenuPopup2, MF_STRING, MYMENU_SAMPLE1, TEXT("Change parameter"));
          AppendMenu(hMenu, MF_POPUP, (UINT_PTR)hMenuPopup2, TEXT("Test"));
          return hMenu;
        }

    void WINAPI CreateAWindow(PassedToDLL *lpParam, DWORD dwStyle)
        {   
          if (nInstances == 0) RegisterDLLWindowClass((LPCWSTR)L"WindowOfDLL");
          HMENU hMenu = CreateDLLWindowMenu();
          nInstances++;
          CommonInfo[nInstances - 1] = lpParam;
          int i = 20 + 4 * (rand() % 10);
          lpParam->p = NewPanningStruct();
          lpParam->hWndChild = CreateWindowEx(0, L"WindowOfDLL", lpParam->title,
                dwStyle,
                i, i, 800, 550, lpParam->hWndParent, hMenu, NULL, NULL);
          if (wcslen(lpParam->filename) > 0)
          {
            LoadBitmapFromBMPFileW(lpParam->hWndChild, lpParam->filename, &(lpParam->hBmp),
                &(lpParam->hPalette));
          } 
        }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...