간단한 콤보 상자를 만드는 방법
이 항목에서는 간단한 콤보 상자에서 항목을 만들고 추가하고 검색하는 방법에 대해 설명합니다. 특히 함께 제공되는 코드 예제에서는 다음 함수를 수행하는 방법을 보여 줍니다.
- 부모 창에 간단한 콤보 상자를 동적으로 만듭니다.
- 항목 목록을 콤보 상자에 추가하고 콤보 상자의 선택 필드에 초기 항목을 표시합니다.
- 사용자가 콤보 상자에서 항목을 선택한 시기를 검색합니다.
- 콤보 상자에서 선택한 항목을 검색합니다.
알아야 하는 작업
기술
필수 구성 요소
- C/C++
- Windows 사용자 인터페이스 프로그래밍
지침
1단계: 콤보 상자의 인스턴스를 만듭니다.
예제 애플리케이션은 CreateWindow 함수를 호출하여 애플리케이션 창의 자식 창을 만듭니다. WC_COMBOBOX 창 스타일은 이것이 콤보 상자임을 지정합니다.
// Create the Combobox
//
// Uses the CreateWindow function to create a child window of
// the application window. The WC_COMBOBOX window style specifies
// that it is a combobox.
int xpos = 100; // Horizontal position of the window.
int ypos = 100; // Vertical position of the window.
int nwidth = 200; // Width of the window
int nheight = 200; // Height of the window
HWND hwndParent = m_hwnd; // Handle to the parent window
HWND hWndComboBox = CreateWindow(WC_COMBOBOX, TEXT(""),
CBS_DROPDOWN | CBS_HASSTRINGS | WS_CHILD | WS_OVERLAPPED | WS_VISIBLE,
xpos, ypos, nwidth, nheight, hwndParent, NULL, HINST_THISCOMPONENT,
NULL);
2단계: 항목 목록과 함께 콤보 상자를 로드합니다.
애플리케이션은 목록의 각 항목에 대한 CB_ADDSTRING 메시지를 보냅니다. 목록이 로드되면 애플리케이션은 CB_SETCURSEL 메시지를 보내 콤보 상자 선택 필드에 초기 항목을 표시합니다.
// load the combobox with item list.
// Send a CB_ADDSTRING message to load each item
TCHAR Planets[9][10] =
{
TEXT("Mercury"), TEXT("Venus"), TEXT("Terra"), TEXT("Mars"),
TEXT("Jupiter"), TEXT("Saturn"), TEXT("Uranus"), TEXT("Neptune"),
TEXT("Pluto??")
};
TCHAR A[16];
int k = 0;
memset(&A,0,sizeof(A));
for (k = 0; k <= 8; k += 1)
{
wcscpy_s(A, sizeof(A)/sizeof(TCHAR), (TCHAR*)Planets[k]);
// Add string to combobox.
SendMessage(hWndComboBox,(UINT) CB_ADDSTRING,(WPARAM) 0,(LPARAM) A);
}
// Send the CB_SETCURSEL message to display an initial item
// in the selection field
SendMessage(hWndComboBox, CB_SETCURSEL, (WPARAM)2, (LPARAM)0);
3단계: 사용자가 항목을 선택하는 시기를 감지하고 콤보 상자에서 검색합니다.
사용자가 목록에서 선택할 때 콤보 상자는 WM_COMMAND 메시지를 통해 부모 창에 CBN_SELCHANGE 알림을 보냅니다. 애플리케이션은 알림 메시지의 lParam 필드에서 콤보 상자에 대한 핸들을 검색하고 선택한 목록 항목의 인덱스를 검색하기 위해 CB_GETCURSEL 메시지를 콤보 상자에 보냅니다. 항목 인덱스를 가져온 후 애플리케이션은 항목을 가져오기 위해 CB_GETLBTEXT 메시지를 보냅니다. 그런 다음, 메시지 상자에 항목을 표시합니다.
참고
항목이 콤보 상자 선택 필드에 배치되기 전에 CBN_SELCHANGE 알림이 전송되고 처리됩니다. 따라서 이 예제에서는 선택한 항목이 메시지 상자를 닫을 때까지 선택 필드에 표시되지 않습니다.
switch (message)
{
case WM_COMMAND:
if(HIWORD(wParam) == CBN_SELCHANGE)
// If the user makes a selection from the list:
// Send CB_GETCURSEL message to get the index of the selected list item.
// Send CB_GETLBTEXT message to get the item.
// Display the item in a messagebox.
{
int ItemIndex = SendMessage((HWND) lParam, (UINT) CB_GETCURSEL,
(WPARAM) 0, (LPARAM) 0);
TCHAR ListItem[256];
(TCHAR) SendMessage((HWND) lParam, (UINT) CB_GETLBTEXT,
(WPARAM) ItemIndex, (LPARAM) ListItem);
MessageBox(hwnd, (LPCWSTR) ListItem, TEXT("Item Selected"), MB_OK);
}
wasHandled = true;
result = 0;
break;
전체 예제
// Windows Header Files:
#include <windows.h>
#include <CommCtrl.h>
// C RunTime Header Files
#include <math.h>
#include <objbase.h>
/******************************************************************
* *
* Macros *
* *
******************************************************************/
template<class Interface>
inline void
SafeRelease(
Interface **ppInterfaceToRelease
)
{
if (*ppInterfaceToRelease != NULL)
{
(*ppInterfaceToRelease)->Release();
(*ppInterfaceToRelease) = NULL;
}
}
#ifndef Assert
#if defined( DEBUG ) || defined( _DEBUG )
#define Assert(b) if (!(b)) {OutputDebugStringA("Assert: " #b "\n");}
#else
#define Assert(b)
#endif //DEBUG || _DEBUG
#endif
#ifndef HINST_THISCOMPONENT
EXTERN_C IMAGE_DOS_HEADER __ImageBase;
#define HINST_THISCOMPONENT ((HINSTANCE)&__ImageBase)
#endif
/******************************************************************
* *
* DemoApp *
* *
******************************************************************/
class DemoApp
{
public:
DemoApp();
~DemoApp();
HRESULT Initialize();
void RunMessageLoop();
private:
HRESULT CreateResources();
void DiscardResources();
static LRESULT CALLBACK WndProc(
HWND hWnd,
UINT message,
WPARAM wParam,
LPARAM lParam
);
private:
HWND m_hwnd;
};
#include "SimpleComboBox.h"
/******************************************************************
* *
* The application entry point. *
* *
******************************************************************/
int WINAPI WinMain(
HINSTANCE /* hInstance */,
HINSTANCE /* hPrevInstance */,
LPSTR /* lpCmdLine */,
int /* nCmdShow */
)
{
// Ignore the return value because we want to run the program even in the
// unlikely event that HeapSetInformation fails.
HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0);
if (SUCCEEDED(CoInitialize(NULL)))
{
{
DemoApp app;
if (SUCCEEDED(app.Initialize()))
{
app.RunMessageLoop();
}
}
CoUninitialize();
}
return 0;
}
/******************************************************************
* *
* DemoApp::DemoApp constructor *
* *
* Initialize member data. *
* *
******************************************************************/
DemoApp::DemoApp() :
m_hwnd(NULL)
{
}
/******************************************************************
* *
* Release resources. *
* *
******************************************************************/
DemoApp::~DemoApp()
{
// TODO: Release app resource here.
}
/*******************************************************************
* *
* Create the application window and the combobox. *
* *
*******************************************************************/
HRESULT DemoApp::Initialize()
{
HRESULT hr;
// Register the window class.
WNDCLASSEX wcex = { sizeof(WNDCLASSEX) };
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = DemoApp::WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = sizeof(LONG_PTR);
wcex.hInstance = HINST_THISCOMPONENT;
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);;
wcex.lpszMenuName = NULL;
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.lpszClassName = TEXT("DemoApp");
RegisterClassEx(&wcex);
// Create the application window.
//
// Because the CreateWindow function takes its size in pixels, we
// obtain the system DPI and use it to scale the window size.
int dpiX = 0;
int dpiY = 0;
HDC hdc = GetDC(NULL);
if (hdc)
{
dpiX = GetDeviceCaps(hdc, LOGPIXELSX);
dpiY = GetDeviceCaps(hdc, LOGPIXELSY);
ReleaseDC(NULL, hdc);
}
m_hwnd = CreateWindow(
TEXT("DemoApp"),
TEXT("Simple Combo Box Example"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
static_cast<UINT>(ceil(640.f * dpiX / 96.f)),
static_cast<UINT>(ceil(480.f * dpiY / 96.f)),
NULL,
NULL,
HINST_THISCOMPONENT,
this
);
hr = m_hwnd ? S_OK : E_FAIL;
if (SUCCEEDED(hr))
{
ShowWindow(m_hwnd, SW_SHOWNORMAL);
UpdateWindow(m_hwnd);
}
// Create the Combobox
//
// Uses the CreateWindow function to create a child window of
// the application window. The WC_COMBOBOX window style specifies
// that it is a combobox.
int xpos = 100; // Horizontal position of the window.
int ypos = 100; // Vertical position of the window.
int nwidth = 200; // Width of the window
int nheight = 200; // Height of the window
HWND hwndParent = m_hwnd; // Handle to the parent window
HWND hWndComboBox = CreateWindow(WC_COMBOBOX, TEXT(""),
CBS_DROPDOWN | CBS_HASSTRINGS | WS_CHILD | WS_OVERLAPPED | WS_VISIBLE,
xpos, ypos, nwidth, nheight, hwndParent, NULL, HINST_THISCOMPONENT,
NULL);
// load the combobox with item list.
// Send a CB_ADDSTRING message to load each item
TCHAR Planets[9][10] =
{
TEXT("Mercury"), TEXT("Venus"), TEXT("Terra"), TEXT("Mars"),
TEXT("Jupiter"), TEXT("Saturn"), TEXT("Uranus"), TEXT("Neptune"),
TEXT("Pluto??")
};
TCHAR A[16];
int k = 0;
memset(&A,0,sizeof(A));
for (k = 0; k <= 8; k += 1)
{
wcscpy_s(A, sizeof(A)/sizeof(TCHAR), (TCHAR*)Planets[k]);
// Add string to combobox.
SendMessage(hWndComboBox,(UINT) CB_ADDSTRING,(WPARAM) 0,(LPARAM) A);
}
// Send the CB_SETCURSEL message to display an initial item
// in the selection field
SendMessage(hWndComboBox, CB_SETCURSEL, (WPARAM)2, (LPARAM)0);
return hr;
}
/******************************************************************
* *
* The main window's message loop. *
* *
******************************************************************/
void DemoApp::RunMessageLoop()
{
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
/******************************************************************
* *
* The window's message handler. *
* *
******************************************************************/
LRESULT CALLBACK DemoApp::WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
LRESULT result = 0;
if (message == WM_CREATE)
{
LPCREATESTRUCT pcs = (LPCREATESTRUCT)lParam;
DemoApp *pDemoApp = (DemoApp *)pcs->lpCreateParams;
::SetWindowLongPtrW(
hwnd,
GWLP_USERDATA,
PtrToUlong(pDemoApp)
);
result = 1;
}
else
{
DemoApp *pDemoApp = reinterpret_cast<DemoApp *>(static_cast<LONG_PTR>(
::GetWindowLongPtrW(
hwnd,
GWLP_USERDATA
)));
bool wasHandled = false;
if (pDemoApp)
{
switch (message)
{
case WM_COMMAND:
if(HIWORD(wParam) == CBN_SELCHANGE)
// If the user makes a selection from the list:
// Send CB_GETCURSEL message to get the index of the selected list item.
// Send CB_GETLBTEXT message to get the item.
// Display the item in a messagebox.
{
int ItemIndex = SendMessage((HWND) lParam, (UINT) CB_GETCURSEL,
(WPARAM) 0, (LPARAM) 0);
TCHAR ListItem[256];
(TCHAR) SendMessage((HWND) lParam, (UINT) CB_GETLBTEXT,
(WPARAM) ItemIndex, (LPARAM) ListItem);
MessageBox(hwnd, (LPCWSTR) ListItem, TEXT("Item Selected"), MB_OK);
}
wasHandled = true;
result = 0;
break;
case WM_DISPLAYCHANGE:
{
InvalidateRect(hwnd, NULL, FALSE);
}
wasHandled = true;
result = 0;
break;
case WM_DESTROY:
{
PostQuitMessage(0);
}
wasHandled = true;
result = 1;
break;
}
}
if (!wasHandled)
{
result = DefWindowProc(hwnd, message, wParam, lParam);
}
}
return result;
관련 항목