2013-12-12 2 views
2

Я только начинаю изучать winapi, и я хочу сделать простую форму с двумя кнопками и текстовым полем. Когда я нажимаю одну кнопку, я хочу, чтобы текстовое поле говорило одно, а когда я нажимаю другую кнопку, я хочу, чтобы она говорила что-то еще. Чтобы разграничить две кнопки, я должен знать их идентификаторы управления, которые находятся в нижней части wParam в сообщении WM_COMMAND. Я думаю, что я должен сам указывать эти ID (или делает это по умолчанию Windows? Если да, то как я могу получить идентификаторы?) В параметре hMenu функции CreateWindowEx(). Однако я не могу найти документацию по объекту HMENU или какое-либо объяснение того, как ее использовать. Что такое HMENU?Что такое winapi HMENU и как его использовать?

+0

Это дескриптор меню. Вы помещаете любой идентификатор, который вы хотите, в качестве аргумента в 'CreateWindow (Ex)'. – chris

ответ

5

HMENU - это ручка для меню, например. как создано LoadMenu (что создает меню из спецификации в ресурсе).

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

При создании дочернего окна просто введите id HMENU.

Общим соглашением является использование -1 для идентификатора «не заботьтесь». Для этого вам лучше не использовать 0, потому что 0 является идентификатором кнопки OK с символическим именем IDOK.

РЕДАКТИРОВАТЬ: Значение IDOK документирована (правильно) как 1, в документации MessageBox. Я не знаю, откуда появилась информация, которую я передал выше. Тем не менее, может быть хорошей идеей избежать 0 как id.


Вот несколько примеров, иллюстрирующих базовый подход. Он не будет компилироваться в вашей системе, потому что используемые здесь заголовки являются моими. Кроме того, в то время как код работает, это просто своего рода скелет, чтобы поддержать другой код, чтобы заменить более правильным кодом позже, поэтому не ставьте слишком много веса на проектных решений и т.д.

#pragma once 
// Copyright (c) 2013 Alf P. Steinbach 

#include <rfc/winapi/Atomlike_id.h>     // Atomlike_id, pseudopointer_from 
#include <rfc/winapi/geometry/Rect.h>    // winapi::geometry::Rect 
#include <rfc/winapi/gui/general_windowclass.h>  // general_windowclass_atom 
#include <rfc/winapi/gui/windowclass_names.h>  // richedit_classname 
#include <rfc/winapi/gui/Window_handle_.h>   // Window_handle, Toplevel_window_handle 

namespace winapi{ namespace gui{ 

    inline 
    auto new_toplevel_window(
     Toplevel_window_handle const owner = Toplevel_window_handle(nullptr) 
     ) 
     -> Toplevel_window_handle 
    { 
     HWND const handle = ::CreateWindow(
      general_windowclass_atom().raw(), 
      L"",    // Title 
      WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, 
      CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 
      owner, 
      HMENU(), 
      ::GetModuleHandle(nullptr), 
      nullptr    // param 
      ); 
     hopefully(handle != 0) 
      || fail("::CreateWindow", ::GetLastError()); 
     return Toplevel_window_handle(handle); 
    } 

    inline 
    auto new_child_window(
     Atomlike_id const  windowclass_id, 
     Window_handle const  parent, 
     geometry::Rect const& placement  = geometry::Rect(), 
     DWORD const    stylebits  = 0, 
     int const    id    = -1 
     ) 
     -> Child_window_handle 
    { 
     if(windowclass_id == Atomlike_id(richedit_classname)) 
     { 
      static auto const richedit_dll_name = L"Msftedit.dll"; 
      if(!GetModuleHandle(richedit_dll_name)) 
      { 
       ::LoadLibrary(richedit_dll_name) 
        || fail("LoadLibrary(\"Msftedit.dll\")", ::GetLastError()); 
      } 
     } 
     auto const& r = placement; 
     HWND const handle = ::CreateWindow(
      windowclass_id.raw(), 
      L"",     // Text 
      stylebits | WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS, 
      r.x(), r.y(), r.w(), r.h(),   // CW_USEDEFAULT is not valid for child window. 
      parent, 
      reinterpret_cast<HMENU>(id), 
      ::GetModuleHandle(nullptr), 
      nullptr     // param 
      ); 
     hopefully(handle != 0) 
      || fail("::CreateWindow", ::GetLastError()); 
     return Child_window_handle(handle); 
    } 

} } // namespace winapi::gui 
+0

Где я могу найти эту RFC-библиотеку, если вы не возражаете, чтобы я спросил? – chris

+0

«Он не будет компилироваться в вашей системе, потому что используемые здесь заголовки являются моими». –

+0

@BenVoigt, что, без репо или что-нибудь еще? Это новый подход ко мне, и я всегда ищу их и вижу, что мне нравится и не нравится в них. Жаль, все ли они приватные. – chris

Смежные вопросы