Modeless diyalog kutusu, kullanıcının veri girişi yapmasını ve kapatılmadan, ana program penceresi ile ilgili işlemlerin yapılmasına olanak sağlar.
Modeless diyalog kutuları CreateDialog() fonksiyonu ile oluşturulur.
Modeless diyalog kutusu açık kalsa bile kullanıcı ana program penceresi ile ilgili işlemleri yapabilir.
Modeless diyalog kutusu, bir pencere menüsü, bir başlık çubuğu ve ince bir sınır çizgisi olan bir açılır penceredir. Bu özellikleri içermesi içn modeless diyalog kutusu WS_POPUP, WS_SYSMENU, WS_CAPTION, ve WS_BORDER özellikleri ile tanımlanmalıdır. WS_VISIBLE özelliği ile tanımlanmadığı sürece, sistem diyalog kutusunu otomatik olarak ekranda göstermez.
Uygulamalar bir modeless diyalog kutusu oluşturmak için aşağıdaki fonksiyonlardan birini kullanır:
CreateDialog(): Bu fonksiyon, bir resource dosyası içinde yer alan bir diyalog kutusu şablonunun adını veya tanımlayıcısını kullanarak bir modeless diyalog kutusu oluşturur.
CreateDialogIndirect(): Bu fonksiyon, bir diyalog kutusu şablonunu içeren bir bellek nesnesinin Handle değerini kullanarak bir modeless diyalog kutusu oluşturur.
CreateDialog() veya CreateDialogIndirect() fonksiyonları modeless bir diyalog kutusu oluşturduklarında, dialog kutusuna ait bir pencere Handle değeri geri döndürürler. Programlar, bu Handle değerini ShowWindow() fonksiyonuna geçirerek diyalog kutusunu ekranda gösterirler.
Modeless bir diyalog kutusu ana penceresini devre dışı bırakmaz ve mesaj yollamaz. Diyalog kutusu oluşturulduğunda, sistem kutuyu aktif pencere olarak belirler, kullanıcı veya sistem aktif pencereyi istediği zaman değiştirebilir. Diyalog kutusu aktif özelliğini kaybetse bile, ana program penceresinin üzerinde kalır.
Program, kullanıcı tarafından yapılan giriş işlemlerine karşılık olarak oluşturulan mesajları alma ve diyalog kutusuna iletme işini yürütürler. Uygulamalar genelde bu işlem için ana mesaj döngüsünü kullanırlar. Kullanıcının diyalog kutusu üzerindeki kontroller arasında klavye ile hareket etmek ve işlem yapmak için IsDialogMessage() fonksiyonu kullanılır.
Modeless diyalog kutusu, programa bir değer geri döndürmez, ancak diyalog kutusu mesaj işlem fonksiyonu SendMessage() fonkisyonu ile ana pencereye bilgi gönderebilir.
Uygulamalar sona ermeden önce DestroyWindow() fonksiyonunu kullanarak bütün modeless diyalog kutularını yok etmelidir. Genel olarak, diyalog kutusu mesaj işlem fonksiyonu içinde iptal içerikli kullanıcı girişlerine karşılık olarak DestroyWindow() fonksiyonu ile diyalog kutuları yok edilir, ancak diyalog kutularının yok edilmediği durumlar göz önüne alınarak uygulamaların DestroyWindow() fonksiyonunu çağırması gerekir.
Diyalog kutusu kendini yok ettiğinde, diyalog kutusuna tahsis edilen global bir pencere Hanle değerine NULL değeri atanır.
Diyalog kutusu mesaj işlem fonksiyonu modeless bir diyalog kutusunu yok etmek için EndDialog() fonksiyonunu çağırmaz.
Bütün diyalog kutusu mesaj işlem fonksiyonlarının genel yapısı aşağıdaki şekildedir:
BOOL CALLBACK DlgProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
// Diğer mesajlar
default:
return FALSE;
}
}
Şimdi, programımıza modeless bir diyalog kutusu eklemeye çalışalım:
resource.rc ve resource.h dosyaları, modal diyalog kutusu oluşturmada kullandığımız dosyalarla aynıdır.
main.c
Aşağıdaki ilk satır programın başına global değer olarak eklenir. Diğer satırlarda yer alan ana program mesaj döngüsünde, diyalog kutusu açık değilse (IsWindow() fonksiyonu ile kontrol edilir) veya mesaj diyalog kutusu ile ilgili değilse (IsDialogMessage() fonksiyonu ile kontrol edilir), mesaj ana pencere veya mevcutsa diğer pencerelerin mesaj işlem fonksiyonlarına gönderilir.
HWND hwndDialog = NULL;
while (GetMessage (&messages, NULL, 0, 0) > 0) {
if (!IsWindow(hwndDialog) || !IsDialogMessage(hwndDialog, &messages)) {
TranslateMessage(&messages);
DispatchMessage(&messages);
}
}
WindowProcedure() fonksiyonu içinde renkli olarak gösterilen satırlar ile WM_COMMAND mesajına işlem yapılarak IDM_BASLIK_DEG menü seçeneği altında CreateDialog() fonksiyonu ile modeless bir diyalog kutusu oluşturulur ve ShowWindow() fonksiyonu ile ekranda gösterilir.
Ayrıca, modeless diyalog kutusuna gelen mesajlara işlem yapmak üzere, WndProcDlg() isimli mesaj işlem fonksiyonu oluşturulur.
LRESULT CALLBACK WindowProcedure (HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
hwndStatic01 = CreateWindowEx(0, "STATIC", "Statik kontrol",
WS_CHILD | WS_VISIBLE | SS_LEFT, 20, 180, 500, 20,
hwnd, (HMENU) IDC_STATIC01, NULL, NULL);
break;
case WM_COMMAND:
switch(LOWORD(wParam)) {
case IDM_BASLIK_DEG:
if (!IsWindow(hwndDialog)) {
hwndDialog = CreateDialog (ghInst, MAKEINTRESOURCE(IDD_VERIBOX),
hwnd, (DLGPROC)WndProcDlg);
ShowWindow(hwndDialog, SW_SHOW);
}
break;
case IDM_CIKIS:
SendMessage(hwnd, WM_CLOSE, 0, 0);
break;
}
break;
case WM_DESTROY:
PostQuitMessage (0);
break;
default:
return DefWindowProc (hwnd, message, wParam, lParam);
}
return 0;
}
BOOL CALLBACK WndProcDlg(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
SetWindowText(hwndStatic01, "Diyalog penceresi oluşturuldu.");
return TRUE;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDOK:
if (!GetDlgItemText(hwndDlg, IDC_EDIT, cdizi, 200)) *cdizi=0;
SetWindowText(GetWindow(hwndDlg, GW_OWNER), cdizi);
SetWindowText(hwndStatic01, "Ana pencere başlığı değiştirildi.");
return TRUE;
case IDCANCEL:
DestroyWindow(hwndDlg);
SetWindowText(hwndStatic01, "Başlık değiştirme iptal edildi.");
hwndDialog = NULL;
return TRUE;
}
break;
}
return FALSE;
}
Program derleme safhasında resource.rc dosyası derlenerek elde edilen resource.res dosyası .exe dosyaya eklenir.
Program çalıştığında:
Programın çalışan en son halinde yer alan dosyalar aşağıdadır:
resource.rc
#include "resource.h"
IDD_VERIBOX DIALOG 70, 10, 200, 60
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Ana Başlık Değiştirme"
FONT 8, "MS Sans Serif"
BEGIN
EDITTEXT IDC_EDIT, 10, 10, 180, 14
DEFPUSHBUTTON "&OK", IDOK, 30, 35, 50, 14
PUSHBUTTON "&Cancel", IDCANCEL, 120, 35, 50, 14
END
IDR_MENU MENU
BEGIN
POPUP "&İşlemler"
BEGIN
MENUITEM "&Başlık değiştirme", IDM_BASLIK_DEG
MENUITEM "&Çıkış", IDM_CIKIS
END
END
resource.h
#include <windows.h>
#define IDD_VERIBOX 301
#define IDR_MENU 401
#define IDC_STATIC01 101
#define IDC_EDIT 201
#define IDM_BASLIK_DEG 11
#define IDM_CIKIS 12
main.c
#include <windows.h>
#include "resource.h"
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
BOOL CALLBACK WndProcDlg(HWND, UINT, WPARAM, LPARAM);
char szClassName[ ] = "WinAPIWindowsApp";
HINSTANCE ghInst;
char cdizi[200];
HWND hwndDialog = NULL;
HWND hwndStatic01;
int WINAPI WinMain (HINSTANCE hThisInstance,
HINSTANCE hPrevInstance,
LPSTR lpszArgument,
int nCmdShow)
{
HWND hwndMain;
MSG messages;
WNDCLASSEX wincl;
ghInst = hThisInstance;
wincl.hInstance = hThisInstance;
wincl.lpszClassName = szClassName;
wincl.lpfnWndProc = WindowProcedure;
wincl.style = CS_DBLCLKS;
wincl.cbSize = sizeof (WNDCLASSEX);
wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
wincl.lpszMenuName = MAKEINTRESOURCE(IDR_MENU);
wincl.cbClsExtra = 0;
wincl.cbWndExtra = 0;
wincl.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
if (!RegisterClassEx (&wincl)) return 0;
hwndMain = CreateWindowEx (0, szClassName, "WinAPI Temel Program",
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
544, 375, HWND_DESKTOP, NULL, hThisInstance, NULL);
if (!hwndMain) return 0;
ShowWindow (hwndMain, nCmdShow);
UpdateWindow(hwndMain);
while (GetMessage (&messages, NULL, 0, 0) > 0) {
if (!IsWindow(hwndDialog) || !IsDialogMessage(hwndDialog, &messages)) {
TranslateMessage(&messages);
DispatchMessage(&messages);
}
}
return messages.wParam;
}
LRESULT CALLBACK WindowProcedure (HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
hwndStatic01 = CreateWindowEx(0, "STATIC", "Statik kontrol",
WS_CHILD | WS_VISIBLE | SS_LEFT, 20, 180, 500, 20,
hwnd, (HMENU) IDC_STATIC01, NULL, NULL);
break;
case WM_COMMAND:
switch(LOWORD(wParam)) {
case IDM_BASLIK_DEG:
if (!IsWindow(hwndDialog)) {
hwndDialog = CreateDialog (ghInst, MAKEINTRESOURCE(IDD_VERIBOX),
hwnd, (DLGPROC)WndProcDlg);
ShowWindow(hwndDialog, SW_SHOW);
}
break;
case IDM_CIKIS:
SendMessage(hwnd, WM_CLOSE, 0, 0);
break;
}
break;
case WM_DESTROY:
PostQuitMessage (0);
break;
default:
return DefWindowProc (hwnd, message, wParam, lParam);
}
return 0;
}
BOOL CALLBACK WndProcDlg(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
SetWindowText(hwndStatic01, "Diyalog penceresi oluşturuldu.");
return TRUE;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDOK:
if (!GetDlgItemText(hwndDlg, IDC_EDIT, cdizi, 200)) *cdizi=0;
SetWindowText(GetWindow(hwndDlg, GW_OWNER), cdizi);
SetWindowText(hwndStatic01, "Ana pencere başlığı değiştirildi.");
return TRUE;
case IDCANCEL:
DestroyWindow(hwndDlg);
SetWindowText(hwndStatic01, "Başlık değiştirme iptal edildi.");
hwndDialog = NULL;
return TRUE;
}
break;
}
return FALSE;
}
Program çalıştığında karşınıza gelecek ekran görüntüsü aşağıdadır: