#winapi #visual-c #combobox #dialog
#winapi #visual-c #выпадающий список #диалоговое
Вопрос:
C Win32, как добавить выпадающее меню в диалоговое окно Win32
Привет,
Я впервые отправляю вопрос в stackoverflow.
Я пытаюсь добавить поле со списком (в menu.cpp ) в диалоговое окно Win32 (в fingerspell.cpp ). Я не очень хорошо разбираюсь в программировании на Win32, и большинство фрагментов примеров msdn рисуют поле со списком внутри окна. Хотя технически диалоговое окно является окном, но у меня не было большого прогресса в изменении кода любого примера окна для обработки диалогового окна. Я был бы очень признателен за рабочий пример.
Грубый набросок кода выглядит следующим образом. fingerspell.cpp creates реализует функцию WinMain, а затем вызывает другие пользовательские классы для рисования внутри этого диалогового окна. Никакие другие элементы управления окном, такие как кнопки, текстовая область и т.д., Не используются.
код для fingerspell.cpp является
#include "fingerspell.h"
extern "C" __declspec(dllexport)bool isGloveDriverInstalled();
extern "C" __declspec(dllimport)bool initialize();
#define RUN( x ) if ( SUCCEEDED( result ) ) { result = x; }
BOOL g_fullscreen = FALSE;
bool portReady;
INT_PTR CALLBACK OptionDialogProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg) {
case WM_INITDIALOG:
if (wParam == IDOK)
return TRUE ;
else
return FALSE ;
break;
case WM_COMMAND:
if (HIWORD(wParam) == BN_CLICKED) {
if (LOWORD(wParam) == IDOK) {
g_fullscreen = TRUE;
EndDialog (hwndDlg, 1) ;
}
else if (LOWORD(wParam) == ID_WINDOW_OPT) {
g_fullscreen = FALSE;
EndDialog (hwndDlg, 1) ;
}
else {
EndDialog (hwndDlg, 0) ;
}
return TRUE ;
}
default:
return FALSE;
break ;
}
}
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
INT_PTR DispOption = DialogBox (hInstance, MAKEINTRESOURCE(IDD_DISPLAY_OPTIONS), NULL, OptionDialogProc) ;
if (DispOption == 0)
return 0 ;
//srand( GetTickCount( ) );
HRESULT result = S_OK;
if (!isGloveDriverInstalled())
{
portReady = FALSE;
MessageBox(NULL, "The Glove Driver is not istalled ", "Error", MB_OK );
}
else
{
if (!initialize())
{
portReady = FALSE;
MessageBox(NULL, "Error Opening Com Port", "Error", MB_OK );
}
else
{
portReady = TRUE;
}
}
RUN( Words ::Create ( "default.txt" ) );
RUN( Window::Create ( ) );
RUN( Render::Create ( ) );
RUN( Art ::Create ( ) );
RUN( Menu ::Create ( ) );
RUN( Window::MessageLoop( ) );
RUN( Menu ::Destroy ( ) );
RUN( Art ::Destroy ( ) );
RUN( Render::Destroy ( ) );
RUN( Window::Destroy ( ) );
RUN( Words ::Destroy ( ) );
if ( FAILED( result ) )
{
MessageBox( GetDesktopWindow( ), "Warning - Fail Code Detected", "Fingerspell 2002", MB_ICONWARNING | MB_OK );
}
return resu<
}
код для menu.cpp . файл, в который я пытаюсь добавить поле со списком.
#include "fingerspell.h"
#include <windows.h> //include all the basics
#include <tchar.h> //string and other mapping macros
#include <string>
HRESULT Menu::Create( )
{
// set menu as the background
Render::SetBackground( ART_MENU );
// clear overlay
Render::Reset( );
Window::SetProc( Proc );
return S_OK;
}
HRESULT Menu::Destroy( void )
{
return S_OK;
}
LRESULT CALLBACK Menu::Proc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
DWORD i ;
const static RECT button_rect[ 8 ] =
{
{ 52, 139, 52 101, 139 50 }, //1. about
{ 55, 212, 55 85, 212 50 }, // 2. learn
{ 67, 280, 67 63, 280 50 }, // 3. exit
{ 397, 137, 397 233, 137 50 }, // 4. Add Delete List.
{ 421, 187, 421 183, 187 50 }, // 5. add word
{ 413, 247, 413 201, 247 50 }, // 6. delete word
{ 450, 300, 450 124, 300 50 }, // 7. practice
{ 473, 349, 473 82, 349 50 }, // 8. test
};
// custom message processing
switch ( uMsg )
{
case WM_CREATE:
return OnCreate(hwnd,reinterpret_cast<CREATESTRUCT*>(lParam));
case WM_MOUSEMOVE: // move is moved, see where is it pointing to.
{
int xPos = GET_X_LPARAM( lParam );
int yPos = GET_Y_LPARAM( lParam );
for ( i = 0; i < 8; i )
{
if ( xPos >= button_rect[ i ].left amp;amp; yPos >= button_rect[ i ].top )
{
if ( xPos < button_rect[ i ].right amp;amp; yPos < button_rect[ i ].bottom )
{
// set selection
Render::SetOverlay( 0, (ART) ( ART_MENU_LEARN i ), button_rect[ i ].left, button_rect[ i ].top );
break;
}
}
}
if ( i == 8 )
{
//remove selection
Render::SetOverlay( 0, ART_NULL, 0, 0 );
}
return 0;
}
case WM_LBUTTONDOWN:
{
switch ( Render::GetOverlay( 0 ) )
{
case ART_MENU_EXIT: // done.
{
Menu::Destroy( );
Learn::Create( );
break;
}
case ART_MENU_LEARN: // done
{
Menu::Destroy( );
About::Create( );
break;
}
case ART_MENU_ABOUT: // done
{
Menu::Destroy( );
Test::Create( );
break;
}
case ART_MENU_TEST: // done.
{
Menu::Destroy( );
Practice::Create( );
break;
}
case ART_MENU_DELETEWORD: // done
{
Menu::Destroy( );
AddWord::Create( );
break;
}
case ART_MENU_ADDDELETELIST:
{
//Menu::Destroy () ;
PostQuitMessage( 0 );
break;
}
case ART_MENU_ADD:
{
Menu::Destroy( );
// About is place holder. should be AddDELETELIST
About::Create( );
break;
}
case ART_MENU_PRACTICE: // done.
{
Menu::Destroy( );
// About is place holder. shd be DELETEWORD.
About::Create( );
break;
}
}
return 0;
}
}
// default message processing
return DefWindowProc( hwnd, uMsg, wParam, lParam );
}
Спасибо.
Комментарии:
1. Используете ли вы visual Studio? В нем есть редактор, который позволит вам перетаскивать элементы управления.
Ответ №1:
Я думаю, что это лучше, чем редактор Visual Studio (который поставляется только с professional)
Ответ №2:
В Vista или более поздней версии используйте простой стиль управления кнопками BS_SPLITBUTTON (WC_BUTTON), а затем обработайте BCN_DROPDOWN для создания своего меню.
Я не пробовал этот фактический код, но этот пример выглядит разумно: http://www.codereflect.com/2009/02/19/how-to-create-a-drop-down-button-in-windows-vista-7 /
Мартин