Combo Kutusunu Alt Sınıf Oluşturma
Bu konuda combo kutularının nasıl alt sınıf oluşturulacağı gösterilmektedir. C++ örnek uygulaması, iki birleşik giriş kutusu içeren bir araç çubuğu penceresi oluşturur. Birleşik giriş kutuları içindeki düzenleme denetimlerini alt sınıf oluşturarak, araç çubuğu penceresi aksi takdirde yoksayılacak olan SEKME, ENTER ve ESC tuşlarını engeller.
Bilmeniz gerekenler
Teknolojileri
Önkoşullar
- C/C++
- Windows Kullanıcı Arayüzü Programlama
Talimat
WM_CREATE İletisini İşleme
Uygulama, alt pencere olarak iki birleşik giriş kutusu denetimi oluşturmak için WM_CREATE iletisini işler.
// Create two combo box child windows.
dwBaseUnits = GetDialogBaseUnits();
hwndCombo1 = CreateWindow(L"COMBOBOX", L"",
CBS_DROPDOWN | WS_CHILD | WS_VISIBLE,
(6 * LOWORD(dwBaseUnits)) / 4,
(2 * HIWORD(dwBaseUnits)) / 8,
(100 * LOWORD(dwBaseUnits)) / 4,
(50 * HIWORD(dwBaseUnits)) / 8,
hwnd, NULL, NULL, NULL);
hwndCombo2 = CreateWindow(L"COMBOBOX", L"",
CBS_DROPDOWN | WS_CHILD | WS_VISIBLE,
(112 * LOWORD(dwBaseUnits)) / 4,
(2 * HIWORD(dwBaseUnits)) / 8,
(100 * LOWORD(dwBaseUnits)) / 4,
(50 * HIWORD(dwBaseUnits)) / 8,
hwnd, NULL, hInst, NULL);
Uygulama daha sonra her birleşik giriş kutusundaki düzenleme denetimlerini (seçim alanları) alt sınıfa alır çünkü bunlar basit ve açılan birleşik giriş kutusu için karakter girişini alır. Son olarak, her düzenleme denetiminin tutamacını almak için ChildWindowFromPoint işlevini çağırır.
Düzenleme denetimlerini alt sınıflandırmak için uygulama, SetWindowLong işlevini çağırır ve sınıf penceresi yordamına olan işaretçiyi, uygulama tarafından tanımlanan SubClassProc işlevine işaret edecek şekilde değiştirir. Özgün pencere yordamının işaretçisi lpfnEditWndProc genel değişkenine kaydedilir.
SubClassProc sekme, ENTER ve ESC tuşlarını ve uygulama tanımlı iletiler (WM_TAB, WM_ESC ve WM_ENTER) göndererek araç çubuğu penceresine bildirir. SubClassProc, çoğu iletiyi özgün pencere yordamına geçirmek için CallWindowProc işlevini kullanır lpfnEditWndProc.
// Get the edit window handle to each combo box.
pt.x = 1;
pt.y = 1;
hwndEdit1 = ChildWindowFromPoint(hwndCombo1, pt);
hwndEdit2 = ChildWindowFromPoint(hwndCombo2, pt);
// Change the window procedure for both edit windows
// to the subclass procedure.
lpfnEditWndProc = (WNDPROC) SetWindowLongPtr(hwndEdit1,
GWLP_WNDPROC, (LONG_PTR) SubClassProc);
SetWindowLongPtr(hwndEdit2, GWLP_WNDPROC, (LONG_PTR) SubClassProc);
WM_SETFOCUS İletisini İşleme
Araç çubuğu penceresi giriş odağını aldığında, odağı hemen araç çubuğundaki ilk birleşik kutuya ayarlar. Bunu yapmak için örnek, WM_SETFOCUS iletisine yanıt olarak SetFocus işlevini çağırır.
case WM_SETFOCUS:
SetFocus(hwndCombo1);
break;
İşlem Application-Defined İletileri
SubClassProc işlevi, kullanıcı birleşik kutuda SEKME, ENTER veya ESC tuşuna bastığında, araç çubuğu penceresine uygulama tanımlı iletiler gönderir. WM_TAB iletisi SEKME tuşu için, WM_ESC iletisi ESC tuşu için ve WM_ENTER iletisi ENTER tuşu için gönderilir.
Örnek, WM_TAB iletisini işleyerek odağı araç çubuğundaki bir sonraki açılır liste kutusuna kaydırır. Odağı ana uygulama penceresine ayarlayarak WM_ESC iletisini işler.
case WM_TAB:
if (GetFocus() == hwndEdit1)
SetFocus(hwndCombo2);
else
SetFocus(hwndCombo1);
break;
case WM_ESC:
hwndCombo = GetFocus() == hwndEdit1 ? hwndCombo1 : hwndCombo2;
// Clear the current selection.
SendMessage(hwndCombo, CB_SETCURSEL,
(WPARAM) (-1), 0);
// Set the focus to the main window.
SetFocus(hwndMain);
break;
örnek, WM_ENTER iletisine yanıt olarak kombinasyon kutusundaki mevcut seçimi geçerli hale getirir ve ardından odağı ana uygulama penceresine yönlendirir. Eğer birleşik giriş kutusu mevcut bir seçim içermiyorsa, örnek, seçim alanının içeriğiyle eşleşen bir liste öğesini aramak için CB_FINDSTRINGEXACT iletisini kullanır. Eşleşme varsa, örnek geçerli seçimi ayarlar; aksi takdirde, yeni bir liste öğesi ekler.
case WM_ENTER:
hwndCombo = GetFocus() == hwndEdit1 ? hwndCombo1 : hwndCombo2;
SetFocus(hwndMain);
// If there is no current selection, set one.
if (SendMessage(hwndCombo, CB_GETCURSEL, 0, 0)
== CB_ERR)
{
if (SendMessage(hwndCombo, WM_GETTEXT,
sizeof(achTemp), (LPARAM) achTemp) == 0)
break; // Empty selection field
dwIndex = SendMessage(hwndCombo,
CB_FINDSTRINGEXACT, (WPARAM) (-1),
(LPARAM) achTemp);
// Add the string, if necessary, and select it.
if (dwIndex == CB_ERR)
dwIndex = SendMessage(hwndCombo, CB_ADDSTRING,
0, (LPARAM) achTemp);
if (dwIndex != CB_ERR)
SendMessage(hwndCombo, CB_SETCURSEL,
dwIndex, 0);
}
break;
// .
// . Process additional messages.
// .
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
Tam örnek
Araç çubuğu için pencere yordamı ve iki açılır kutu için alt sınıf yordamı aşağıdadır.
#define WM_TAB (WM_USER)
#define WM_ESC (WM_USER + 1)
#define WM_ENTER (WM_USER + 2)
// Global variables
HWND hwndMain;
WNDPROC lpfnEditWndProc; // Original wndproc for the combo box
// Prototypes
LRESULT CALLBACK SubClassProc( HWND, UINT, WPARAM, LPARAM );
/********************************************************
FUNCTION: ToolbarWindowProc
PURPOSE: Window procedure for the toolbar window
*********************************************************/
LRESULT CALLBACK ToolbarWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static HWND hwndEdit1;
static HWND hwndEdit2;
static HWND hwndCombo1;
static HWND hwndCombo2;
POINT pt;
DWORD dwBaseUnits;
HWND hwndCombo;
DWORD dwIndex;
char achTemp[256]; // Temporary buffer
switch (msg)
{
case WM_CREATE:
// Create two combo box child windows.
dwBaseUnits = GetDialogBaseUnits();
hwndCombo1 = CreateWindow(L"COMBOBOX", L"",
CBS_DROPDOWN | WS_CHILD | WS_VISIBLE,
(6 * LOWORD(dwBaseUnits)) / 4,
(2 * HIWORD(dwBaseUnits)) / 8,
(100 * LOWORD(dwBaseUnits)) / 4,
(50 * HIWORD(dwBaseUnits)) / 8,
hwnd, NULL, NULL, NULL);
hwndCombo2 = CreateWindow(L"COMBOBOX", L"",
CBS_DROPDOWN | WS_CHILD | WS_VISIBLE,
(112 * LOWORD(dwBaseUnits)) / 4,
(2 * HIWORD(dwBaseUnits)) / 8,
(100 * LOWORD(dwBaseUnits)) / 4,
(50 * HIWORD(dwBaseUnits)) / 8,
hwnd, NULL, hInst, NULL);
// Get the edit window handle to each combo box.
pt.x = 1;
pt.y = 1;
hwndEdit1 = ChildWindowFromPoint(hwndCombo1, pt);
hwndEdit2 = ChildWindowFromPoint(hwndCombo2, pt);
// Change the window procedure for both edit windows
// to the subclass procedure.
lpfnEditWndProc = (WNDPROC) SetWindowLongPtr(hwndEdit1,
GWLP_WNDPROC, (LONG_PTR) SubClassProc);
SetWindowLongPtr(hwndEdit2, GWLP_WNDPROC, (LONG_PTR) SubClassProc);
break;
case WM_SETFOCUS:
SetFocus(hwndCombo1);
break;
case WM_TAB:
if (GetFocus() == hwndEdit1)
SetFocus(hwndCombo2);
else
SetFocus(hwndCombo1);
break;
case WM_ESC:
hwndCombo = GetFocus() == hwndEdit1 ? hwndCombo1 : hwndCombo2;
// Clear the current selection.
SendMessage(hwndCombo, CB_SETCURSEL,
(WPARAM) (-1), 0);
// Set the focus to the main window.
SetFocus(hwndMain);
break;
case WM_ENTER:
hwndCombo = GetFocus() == hwndEdit1 ? hwndCombo1 : hwndCombo2;
SetFocus(hwndMain);
// If there is no current selection, set one.
if (SendMessage(hwndCombo, CB_GETCURSEL, 0, 0)
== CB_ERR)
{
if (SendMessage(hwndCombo, WM_GETTEXT,
sizeof(achTemp), (LPARAM) achTemp) == 0)
break; // Empty selection field
dwIndex = SendMessage(hwndCombo,
CB_FINDSTRINGEXACT, (WPARAM) (-1),
(LPARAM) achTemp);
// Add the string, if necessary, and select it.
if (dwIndex == CB_ERR)
dwIndex = SendMessage(hwndCombo, CB_ADDSTRING,
0, (LPARAM) achTemp);
if (dwIndex != CB_ERR)
SendMessage(hwndCombo, CB_SETCURSEL,
dwIndex, 0);
}
break;
// .
// . Process additional messages.
// .
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
/********************************************************
FUNCTION: SubClassProc
PURPOSE: Process TAB and ESCAPE keys, and pass all
other messages to the class window
procedure.
*********************************************************/
LRESULT CALLBACK SubClassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_KEYDOWN:
switch (wParam)
{
case VK_TAB:
SendMessage(hwndMain, WM_TAB, 0, 0);
return 0;
case VK_ESCAPE:
SendMessage(hwndMain, WM_ESC, 0, 0);
return 0;
case VK_RETURN:
SendMessage(hwndMain, WM_ENTER, 0, 0);
return 0;
}
break;
case WM_KEYUP:
case WM_CHAR:
switch (wParam)
{
case VK_TAB:
case VK_ESCAPE:
case VK_RETURN:
return 0;
}
}
// Call the original window procedure for default processing.
return CallWindowProc(lpfnEditWndProc, hwnd, msg, wParam, lParam);
}
İlgili konular
-
Birleşik Giriş Kutuları Hakkında