Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Bilgileri görüntülemek ve kullanıcıdan giriş istemde bulunabilmek için iletişim kutularını kullanırsınız. Uygulamanız iletişim kutusunu yükleyip başlatır, kullanıcı girişini işler ve kullanıcı görevi tamamladığında iletişim kutusunu yok eder. İletişim kutularını işleme süreci, iletişim kutusunun modlu mu yoksa modsuz mu olduğuna bağlı olarak değişir. Kalıcı iletişim kutusu, kullanıcının uygulamada başka bir pencereyi etkinleştirmeden önce iletişim kutusunu kapatmasını gerektirir. Ancak, kullanıcı farklı uygulamalarda pencereleri etkinleştirebilir. Mod içermeyen bir iletişim kutusu, kullanıcıdan hemen yanıt alınmasını gerektirmez. Denetimleri içeren bir ana pencereye benzer.
Aşağıdaki bölümlerde her iki iletişim kutusu türünün de nasıl kullanılacağı açıklanmıştır.
- Bir İleti Kutusu Görüntüleme
- Modal İletişim Kutusu Oluşturma
- Modsuz İletişim Kutusu Oluşturma
- İletişim Kutusu Başlatma
- Bellekte Şablon Oluşturma
İleti Kutusunu Görüntüleme
Kalıcı iletişim kutusunun en basit biçimi ileti kutusudur. Çoğu uygulama, kullanıcıyı hatalarla ilgili uyarmak ve hata oluştuktan sonra nasıl devam etmek için yol tarifleri almak için ileti kutularını kullanır. MessageBox kullanarak veya MessageBoxExişlevini, görüntülenecek iletiyi ve düğme sayısını ve türünü belirterek bir ileti kutusu oluşturursunuz. Sistem, kendi iletişim kutusu şablonunu ve prosedürünü sağlayarak bir modal iletişim kutusu oluşturur. Kullanıcı ileti kutusunu kapattıktan sonra messageBox veya MessageBoxEx , kullanıcı tarafından ileti kutusunu kapatmak için seçilen düğmeyi tanımlayan bir değer döndürür.
Aşağıdaki örnekte, uygulama bir hata koşulu oluştuktan sonra kullanıcıdan bir eylem isteyen bir ileti kutusu görüntüler. İleti kutusu, hata koşulunu ve nasıl çözüleceğini açıklayan iletiyi görüntüler. MB_YESNO stili, MessageBox kullanıcının nasıl ilerleyeceğini seçebileceği iki düğme sağlamaya yönlendirir:
int DisplayConfirmSaveAsMessageBox()
{
int msgboxID = MessageBox(
NULL,
L"temp.txt already exists.\nDo you want to replace it?",
L"Confirm Save As",
MB_ICONEXCLAMATION | MB_YESNO
);
if (msgboxID == IDYES)
{
// TODO: add code
}
return msgboxID;
}
Aşağıdaki görüntüde, önceki kod örneğinden elde edilen çıkış gösterilmektedir:
Modal İletişim Kutusu Oluşturma
DialogBox işlevini kullanarak modüler bir iletişim kutusu oluşturursunuz. İletişim kutusu şablonu kaynağının tanımlayıcısını veya adını ve iletişim kutusu yordamının işaretçisini belirtmeniz gerekir. DialogBox işlevi şablonu yükler, iletişim kutusunu görüntüler ve kullanıcı iletişim kutusunu kapatana kadar tüm kullanıcı girişini işler.
Aşağıdaki örnekte, kullanıcı bir uygulama menüsünden Öğe Sil'e tıkladığında uygulama modal bir iletişim kutusu görüntüler. İletişim kutusu bir düzenleme denetimi (kullanıcının bir öğenin adını girdiği) ve Tamam ve İptal düğmelerini içerir. Bu denetimlerin denetim tanımlayıcıları sırasıyla ID_ITEMNAME, IDOK ve IDCANCEL'tir.
Örneğin ilk bölümü, modal iletişim kutusunu oluşturan ifadelerden oluşur. Bu ifadeler, uygulamanın ana penceresinin pencere yordamında, sistem IDM_DELETEITEM menü tanımlayıcısını içeren bir WM_COMMAND iletisini aldığında iletişim kutusunu oluşturur. Örneğin ikinci bölümü, düzenleme denetiminin içeriğini alan ve WM_COMMAND iletisi alındığında iletişim kutusunu kapatan iletişim kutusu prosedürüdür.
Aşağıdaki deyimler modal iletişim kutusunu oluşturur. Diyalog kutusu şablonu, uygulamanın yürütülebilir dosyasında bir kaynaktır ve DLG_DELETEITEM kaynak tanımlayıcısına sahiptir.
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDM_DELETEITEM:
if (DialogBox(hinst,
MAKEINTRESOURCE(DLG_DELETEITEM),
hwnd,
(DLGPROC)DeleteItemProc)==IDOK)
{
// Complete the command; szItemName contains the
// name of the item to delete.
}
else
{
// Cancel the command.
}
break;
}
return 0L;
Bu örnekte uygulama, iletişim kutusunun sahip penceresi olarak ana penceresini belirtir. Sistem başlangıçta iletişim kutusunu görüntülediğinde, konumu ana pencerenin istemci alanının sol üst köşesine göre ayarlanır. Uygulama, işleme devam mı yoksa iptal mi edileceğini belirlemek için DialogBox'den dönüş değerini kullanır. Aşağıdaki ifadeler iletişim kutusu işlemini tanımlar.
char szItemName[80]; // receives name of item to delete.
BOOL CALLBACK DeleteItemProc(HWND hwndDlg,
UINT message,
WPARAM wParam,
LPARAM lParam)
{
switch (message)
{
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDOK:
if (!GetDlgItemText(hwndDlg, ID_ITEMNAME, szItemName, 80))
*szItemName=0;
// Fall through.
case IDCANCEL:
EndDialog(hwndDlg, wParam);
return TRUE;
}
}
return FALSE;
}
Bu örnekte yordam, ID_ITEMNAME tarafından tanımlanan düzenleme denetiminden geçerli metni almak için GetDlgItemTextkullanır. Ardından yordam, alınan iletiye bağlı olarak iletişim kutusunun dönüş değerini IDOK veya IDCANCEL olarak ayarlamak ve iletişim kutusunu kapatma işlemini başlatmak için EndDialog işlevini çağırır. IDOK ve IDCANCEL tanımlayıcıları, Tamam düğmesi ve İptal düğmesine denk gelir. Yordam enddialog çağırdıktan sonra, sistem iletişim kutusunu yok etmek için yordama ek iletiler gönderir ve iletişim kutusunun dönüş değerini iletişim kutusunu oluşturan işleve geri döndürür.
Modsuz İletişim Kutusu Oluşturma
CreateDialog işlevini kullanarak modsuz bir iletişim kutusu oluşturursunuz; bu işlem sırasında iletişim kutusu şablon kaynağının tanımlayıcısını veya adını ve iletişim kutusu yordamının işaretçisini belirtirsiniz. CreateDialog şablonu yükler, iletişim kutusunu oluşturur ve isteğe bağlı olarak görüntüler. Uygulamanız, kullanıcı giriş iletilerini almak ve iletişim kutusu yordamına göndermekle sorumludur.
Aşağıdaki örnekte, kullanıcı bir uygulama menüsünden Git'a tıkladığında, uygulama bir modsuz iletişim kutusu (zaten görüntülenmiyorsa) görüntülenir. İletişim kutusunda düzenleme denetimi, onay kutusu ve Tamam ve İptal düğmeleri bulunur. İletişim kutusu şablonu, uygulamanın yürütülebilir dosyasındaki bir kaynaktır ve kaynak tanımlayıcısı DLG_GOTO. Kullanıcı düzenleme denetimine bir satır numarası girer ve satır numarasının geçerli satıra göre olduğunu belirtmek için onay kutusunu denetler. Denetim tanımlayıcıları ID_LINE, ID_ABSREL, IDOK ve IDCANCEL'tir.
Örneğin ilk bölümündeki ifadeler, modalsiz iletişim kutusunu oluşturur. Bu ifadeler, uygulamanın ana penceresinin pencere yordamında, pencere yordamı IDM_GOTO menü tanımlayıcısını içeren bir WM_COMMAND iletisi aldığında, eğer genel değişken zaten geçerli bir tanıtıcı içermiyorsa iletişim kutusunu oluşturur. Örneğin ikinci bölümü uygulamanın ana ileti döngüsüdür. Döngü, kullanıcının bu modsuz iletişim kutusunda iletişim kutusu klavye arabirimini kullanabilmesini sağlamak için IsDialogMessage işlevini içerir. Örneğin üçüncü bölümü, iletişim kutusu prosedürüdür. Yordam, kullanıcı Tamam düğmesine tıkladığında düzenleme denetiminin ve onay kutusunun içeriğini alır. Yordam, kullanıcı İptal düğmesine tıkladığında iletişim kutusunu yok eder.
HWND hwndGoto = NULL; // Window handle of dialog box
...
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDM_GOTO:
if (!IsWindow(hwndGoto))
{
hwndGoto = CreateDialog(hinst,
MAKEINTRESOURCE(DLG_GOTO),
hwnd,
(DLGPROC)GoToProc);
ShowWindow(hwndGoto, SW_SHOW);
}
break;
}
return 0L;
Önceki deyimlerde, CreateDialog yalnızca hwndGoto geçerli bir pencere tutamacı içermiyorsa çağrılır. Bu, uygulamanın aynı anda iki iletişim kutusu görüntülememesini sağlar. Bu denetim yöntemini desteklemek için, iletişim kutusu yok edildiğinde iletişim kutusu yordamının NULL olarak ayarlandığından emin olunmalıdır.
Bir uygulamanın ileti döngüsü aşağıdaki deyimlerden oluşur.
BOOL bRet;
while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0)
{
if (bRet == -1)
{
// Handle the error and possibly exit
}
else if (!IsWindow(hwndGoto) || !IsDialogMessage(hwndGoto, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
Döngü, pencere tanıtıcısının iletişim kutusunun geçerliliğini kontrol eder ve yalnızca tanıtıcı geçerli durumdaysa IsDialogMessage işlevini çağırır. IsDialogMessage yalnızca iletişim kutusuna aitse iletiyi işler. Aksi takdirde, FALSE döndürür ve döngü iletiyi uygun pencereye iletir.
Aşağıdaki ifadeler iletişim kutusu yordamını tanımlar.
int iLine; // Receives line number.
BOOL fRelative; // Receives check box status.
BOOL CALLBACK GoToProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
BOOL fError;
switch (message)
{
case WM_INITDIALOG:
CheckDlgButton(hwndDlg, ID_ABSREL, fRelative);
return TRUE;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDOK:
fRelative = IsDlgButtonChecked(hwndDlg, ID_ABSREL);
iLine = GetDlgItemInt(hwndDlg, ID_LINE, &fError, fRelative);
if (fError)
{
MessageBox(hwndDlg, SZINVALIDNUMBER, SZGOTOERR, MB_OK);
SendDlgItemMessage(hwndDlg, ID_LINE, EM_SETSEL, 0, -1L);
}
else
// Notify the owner window to carry out the task.
return TRUE;
case IDCANCEL:
DestroyWindow(hwndDlg);
hwndGoto = NULL;
return TRUE;
}
}
return FALSE;
}
Önceki ifadelerde, yordam WM_INITDIALOG ve WM_COMMAND iletilerini işler. WM_INITDIALOG işleme sırasında yordam, genel değişkenin geçerli değerini checkDlgButtongeçirerek onay kutusunu başlatır. Ardından yordam, sistemi varsayılan giriş odağını ayarlamaya yönlendirmek için TRUE döndürür.
WM_COMMAND işleme sırasında, yordam yalnızca kullanıcı İptal düğmesine, yani IDCANCEL tanımlayıcısını içeren düğmeye tıklarsa iletişim kutusunu kapatır. Yordam, bir modeless diyalog kutusunu kapatmak için DestroyWindow çağırmalıdır. Yordamın bu değişkene bağımlı diğer deyimlerin doğru çalıştığından emin olmak için değişkeni null olarak da ayarlandığını unutmayın.
Kullanıcı Tamam düğmesine tıklarsa, yordam onay kutusunun geçerli durumunu alır ve fRelative değişkenine atar. Ardından, düzenleme denetiminden satır numarasını almak için değişkenini kullanır. GetDlgItemInt düzenleme denetimindeki metni bir tamsayıya çevirir. fRelative değeri, işlevin sayıyı imzalı veya imzasız bir değer olarak yorumlayıp yorumlamadığını belirler. Düzenleme denetimi metni geçerli bir sayı değilse, GetDlgItemInt fError değişkeninin değerini sıfır olmayan olarak ayarlar. Yordam, bir hata iletisi görüntüleyip görüntülememeyi veya görevi gerçekleştirip gerçekleştirmemeyi belirlemek için bu değeri denetler. Hata durumunda, iletişim kutusu yordamı düzenleme denetimine bir ileti gönderir ve kullanıcının bunu kolayca değiştirebilmesi için denetimdeki metni seçmeye yönlendirir. GetDlgItemInt bir hata döndürmezse, yordam istenen görevin kendisini gerçekleştirebilir veya sahip penceresine bir ileti göndererek işlemi gerçekleştirmeye yönlendirebilir.
İletişim Kutusu Başlatma
WM_INITDIALOG iletisini işlerken iletişim kutusunu ve içeriğini başlatırsınız. En yaygın görev, denetimleri geçerli iletişim kutusu ayarlarını yansıtacak şekilde başlatmaktır. Bir diğer yaygın görev de bir iletişim kutusunu ekranda veya sahip penceresinde ortalamaktır. Bazı iletişim kutuları için kullanışlı bir görev, giriş odağını varsayılan giriş odağını kabul etmek yerine belirtilen denetime ayarlamaktır.
Aşağıdaki örnekte, iletişim kutusu yordamı iletişim kutusunu ortalar ve WM_INITDIALOG iletisini işlerken giriş odağını ayarlar. İletişim kutusunu ortalamak için prosedür, iletişim kutusunun ve sahip penceresinin pencere dikdörtgenlerini alır ve iletişim kutusu için yeni bir konum hesaplar. Giriş odağını ayarlamak için yordam, varsayılan giriş odağının tanımlayıcısını belirlemek için wParam parametresini denetler.
HWND hwndOwner;
RECT rc, rcDlg, rcOwner;
....
case WM_INITDIALOG:
// Get the owner window and dialog box rectangles.
if ((hwndOwner = GetParent(hwndDlg)) == NULL)
{
hwndOwner = GetDesktopWindow();
}
GetWindowRect(hwndOwner, &rcOwner);
GetWindowRect(hwndDlg, &rcDlg);
CopyRect(&rc, &rcOwner);
// Offset the owner and dialog box rectangles so that right and bottom
// values represent the width and height, and then offset the owner again
// to discard space taken up by the dialog box.
OffsetRect(&rcDlg, -rcDlg.left, -rcDlg.top);
OffsetRect(&rc, -rc.left, -rc.top);
OffsetRect(&rc, -rcDlg.right, -rcDlg.bottom);
// The new position is the sum of half the remaining space and the owner's
// original position.
SetWindowPos(hwndDlg,
HWND_TOP,
rcOwner.left + (rc.right / 2),
rcOwner.top + (rc.bottom / 2),
0, 0, // Ignores size arguments.
SWP_NOSIZE);
if (GetDlgCtrlID((HWND) wParam) != ID_ITEMNAME)
{
SetFocus(GetDlgItem(hwndDlg, ID_ITEMNAME));
return FALSE;
}
return TRUE;
Bir önceki ifadelerde, yordam bir iletişim kutusunun sahip pencere tutamacını almak için GetParent işlevini kullanır. İşlev, sahip pencere tutamacını iletişim kutularına, üst pencere tutamacını ise alt pencerelere döndürür. Bir uygulama sahibi olmayan bir iletişim kutusu oluşturabildiğinden, yordam, döndürülen tanıtıcıyı denetler ve gerekirse masaüstü pencere tanıtıcısını elde etmek için GetDesktopWindow işlevini kullanır. Yeni konumu hesapladıktan sonra yordam, iletişim kutusunu taşımak için SetWindowPos işlevini kullanır ve iletişim kutusunun sahip penceresinin üstünde kaldığından emin olmak için HWND_TOP değerini belirtir.
Giriş odağını ayarlamadan önce yordam, varsayılan giriş odağının denetim tanımlayıcısını denetler. Sistem, wParam parametresinde varsayılan giriş odağının pencere tutamacını geçirir. GetDlgCtrlID işlevi, pencere tutamacı tarafından tanımlanan denetimin tanımlayıcısını döndürür. Tanımlayıcı doğru tanımlayıcıyla eşleşmiyorsa, yordam giriş odağını ayarlamak için SetFocusişlevinikullanır. İstediğiniz denetimin pencere tutamacını almak için GetDlgItemişlevi gereklidir.
Bellekte Şablon Oluşturma
Uygulamalar bazen işlenen verilerin geçerli durumuna bağlı olarak iletişim kutularının içeriğini uyarlar veya değiştirir. Bu gibi durumlarda, tüm olası iletişim kutusu şablonlarını uygulamanın yürütülebilir dosyasında kaynak olarak sağlamak pratik değildir. Ancak bellekte şablon oluşturmak, uygulamaya herhangi bir duruma uyum sağlamak için daha fazla esneklik sağlar.
Aşağıdaki örnekte, uygulama bir ileti ve Tamam ile Yardım düğmeleri içeren bir modlu iletişim kutusu için bellekte bir şablon oluşturur.
İletişim kutusu şablonunda, iletişim kutusu ve düğme başlıkları gibi tüm karakter dizeleri Unicode dizeleri olmalıdır. Bu örnekte, bu Unicode dizelerini oluşturmak için MultiByteToWideCharişlevi kullanılmaktadır.
İletişim kutusu şablonundaki DLGITEMTEMPLATE yapıları DWORD sınırlarına hizalanmalıdır. Bu yapıları hizalamak için, bu örnek bir giriş göstergesi alan ve DWORD sınırına hizalanmış en yakın göstergesi döndüren bir yardımcı fonksiyon kullanır.
#define ID_HELP 150
#define ID_TEXT 200
LPWORD lpwAlign(LPWORD lpIn)
{
ULONG ul;
ul = (ULONG)lpIn;
ul ++;
ul >>=1;
ul <<=1;
return (LPWORD)ul;
}
LRESULT DisplayMyMessage(HINSTANCE hinst, HWND hwndOwner, LPSTR lpszMessage)
{
HGLOBAL hgbl;
LPDLGTEMPLATE lpdt;
LPDLGITEMTEMPLATE lpdit;
LPWORD lpw;
LPWSTR lpwsz;
LRESULT ret;
int nchar;
hgbl = GlobalAlloc(GMEM_ZEROINIT, 1024);
if (!hgbl)
return -1;
lpdt = (LPDLGTEMPLATE)GlobalLock(hgbl);
// Define a dialog box.
lpdt->style = WS_POPUP | WS_BORDER | WS_SYSMENU | DS_MODALFRAME | WS_CAPTION;
lpdt->cdit = 3; // Number of controls
lpdt->x = 10; lpdt->y = 10;
lpdt->cx = 100; lpdt->cy = 100;
lpw = (LPWORD)(lpdt + 1);
*lpw++ = 0; // No menu
*lpw++ = 0; // Predefined dialog box class (by default)
lpwsz = (LPWSTR)lpw;
nchar = 1 + MultiByteToWideChar(CP_ACP, 0, "My Dialog", -1, lpwsz, 50);
lpw += nchar;
//-----------------------
// Define an OK button.
//-----------------------
lpw = lpwAlign(lpw); // Align DLGITEMTEMPLATE on DWORD boundary
lpdit = (LPDLGITEMTEMPLATE)lpw;
lpdit->x = 10; lpdit->y = 70;
lpdit->cx = 80; lpdit->cy = 20;
lpdit->id = IDOK; // OK button identifier
lpdit->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON;
lpw = (LPWORD)(lpdit + 1);
*lpw++ = 0xFFFF;
*lpw++ = 0x0080; // Button class
lpwsz = (LPWSTR)lpw;
nchar = 1 + MultiByteToWideChar(CP_ACP, 0, "OK", -1, lpwsz, 50);
lpw += nchar;
*lpw++ = 0; // No creation data
//-----------------------
// Define a Help button.
//-----------------------
lpw = lpwAlign(lpw); // Align DLGITEMTEMPLATE on DWORD boundary
lpdit = (LPDLGITEMTEMPLATE)lpw;
lpdit->x = 55; lpdit->y = 10;
lpdit->cx = 40; lpdit->cy = 20;
lpdit->id = ID_HELP; // Help button identifier
lpdit->style = WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON;
lpw = (LPWORD)(lpdit + 1);
*lpw++ = 0xFFFF;
*lpw++ = 0x0080; // Button class atom
lpwsz = (LPWSTR)lpw;
nchar = 1 + MultiByteToWideChar(CP_ACP, 0, "Help", -1, lpwsz, 50);
lpw += nchar;
*lpw++ = 0; // No creation data
//-----------------------
// Define a static text control.
//-----------------------
lpw = lpwAlign(lpw); // Align DLGITEMTEMPLATE on DWORD boundary
lpdit = (LPDLGITEMTEMPLATE)lpw;
lpdit->x = 10; lpdit->y = 10;
lpdit->cx = 40; lpdit->cy = 20;
lpdit->id = ID_TEXT; // Text identifier
lpdit->style = WS_CHILD | WS_VISIBLE | SS_LEFT;
lpw = (LPWORD)(lpdit + 1);
*lpw++ = 0xFFFF;
*lpw++ = 0x0082; // Static class
for (lpwsz = (LPWSTR)lpw; *lpwsz++ = (WCHAR)*lpszMessage++;);
lpw = (LPWORD)lpwsz;
*lpw++ = 0; // No creation data
GlobalUnlock(hgbl);
ret = DialogBoxIndirect(hinst,
(LPDLGTEMPLATE)hgbl,
hwndOwner,
(DLGPROC)DialogProc);
GlobalFree(hgbl);
return ret;
}