платформа Win32 - Туториалы Iczelion'a на русском, адаптированные для FreeBasic. Урок 10 - Диалоговое окно как основное

Предыдущая тема Следующая тема Перейти вниз

платформа Win32 - Туториалы Iczelion'a на русском, адаптированные для FreeBasic. Урок 10 - Диалоговое окно как основное

Сообщение  electrik в Пн Июн 29, 2009 5:43 pm

Win32 API. Урок 10. Диалоговое окно как основное

Теперь время для действительно интересной темы, относящейся к GUI, о диалоговом окне. В этом туториале (и в следующем) мы научимся как использовать диалоговое окно в качестве основного.


Теория:

Если вы изучили примеры в предыдущем туториалe достаточно подробно, вы заметили, что вы не могли перемещать фокус ввода от одного дочернего окна на другое, используя кнопку Tab. Вы могли сделать это только кликнув на нужном контроле, чтобы перевести на него фокус. Это довольно неудобно. Также вы могли заметить, что изменился цвет родительского окна на серый. Это было сделано для того, чтобы цвет дочерних окон не контрастировал с клиентской областью родительского окна. Есть путь, чтобы обойти эту проблему, но он не очень прост. Вы должны сабклассить все дочерние элементы управления в вашем родительском окне.

Причина того, почему возникают подобные неудобства состоят в том, что дочерние окна изначально проектировались для работы с диалоговым окном, а не с обычным.
Цвет дочернего окна по умолчанию серый, так как это обычный цвет диалогового окна.

Прежде чем мы углубимся в детали, мы должны сначала узнать, что такое диалоговое окно. Диалоговое окно - это не что иное, как обычное окно, которое спроектировано для работы с дочерними элементами управления. Windows также предоставляет внутренний "менеджер диалоговых окон", который воплощает большую часть диалоговой логики, такую как перемещение фокуса ввода, когда юзер нажимает Tab, нажатие кнопки по умолчанию, если нажата кнопка 'Enter, и так далее, так чтобы программисты могли заниматься более высокоуровневыми задачами. Поскольку диалоговое окно можно считать "черным ящиком" (это означает то, что вы не обязаны знать, как
работает диалоговое окно, для того, чтобы использовать его), вы должны только знать, как с ним взаимодействовать. Это принцип объектно-ориентированного
программирования, называемого скрытием информации. Если черный ящик спроектирован совершенно, пользователь может использовать его не зная, как он работает.
Правда, загвоздка в том, что черный ящик должен быть совершенным, это труднодостижимо в реальном мире. Win32 API также спроектирован как черный ящик.

Ладно, похоже, что мы немного отклонились. Давайте вернемся к нашему сюжету. Диалоговые окна спроектированы так, чтобы снизить нагрузку на программиста.
Обычно, если вы помещаете дочерний контрол на обычное окно, вы должны сабклассить их и самостоятельно обрабатывать нажатия на клавиши. Но если вы помещаете их на диалоговое окно, оно обработает их за вас. Вы только должны как получать информацию, вводимую пользователем, или как посылать команды окну. Диалоговое окно определяется как ресурс (похожим образом, как и меню). Вы пишете шаблон диалогового окна, описывая характеристики диалогового окна и его контролов, а затем компилируете его с помощью редактора ресурсов.

Обратите внимание, что все ресурсы располагаются в одном скрипте ресурсов. Вы можете использовать любой текстовый редактор, чтобы написать шаблон диалогового окна, но я бы не рекомендовал это. Вы должны использовать редактор ресурсов, чтобы сделать визуально расположить дочерние окна. Существует несколько прекрасных редакторов ресурсов. К большинству из основных компиляторов прилагаются подобные редакторы. Вы можете использовать их, чтобы создать скрипт ресурса. После этого стоит вырезать лишние линии, например, те, которые относятся к MFC.

Есть два основных вида диалоговых окон: модальные и независимые. Независимые диалоговые окна дают вам возможность перемещать фокус ввода на другие окна.
Пример - диалоговое окно 'Find' в MS Word. Есть два подтипа модальных диалоговых окон: модальные к приложению и модальные к системе. Первые не дают вам переключаться на другое окно того же приложения, но вы можете переключиться на другое приложение. Вторые не дают вам возможности переключиться на любое другое окно.

Независимое диалоговое окно создается с помощью вызова функции CreateDialogParam. Модальное диалоговое окно создается вызовом DialogBoxParam. Единственное Различие между диалоговым окном, модальным отношению к приложению, и диалоговым окном, модальным по отношению к системе, - это стиль DS_SYSMODAL. Если вы включите стиль DS_SYSMODAL в шаблон диалогового окна, это диалоговое окно будет модальным к системе.

Вы можете взаимодействовать с любым дочерним элементом управления на диалоговом окне с помощью функции SendDlgItemMessage. Ее синтакс следующий:

function SendDlgItemMessage _
(byval hwndDlg as HWND, _
byval idControl as integer, _
byval uMsg as UINT, _
byval wParam as WPARAM, _
byval lParam as LPARAM) as LRESULT

Эта API-функция неоценимо полезна при взаимодействии с дочерним окном. Например, если вы хотите получить текст с контрола edit, вы можете сделать следующее:

SendDlgItemMessage(hDlg, ID_EDITBOX, WM_GETTEXT, 256, @text_buffer)

Чтобы знать, какое сообщение когда посылать, вы должны проконсультироваться с вашим Win32 API-справочником.

Windows также предоставляет несколько специальных API-функций, заточенных под дочерние окна, для быстрого получения и установки нужных данных, например, GetDlgItemText, CheckDlgButton и т.д. Эти специальные функции созданы, чтобы программисту не приходилось выяснять каждый раз значения wparam и lparam.
Как правило, вы должны использовать данные функции, если хотите, чтобы управление кодом было легче. Используйте SendDlgItemMessage только, если нет соответствующей API-функции. Менеджер диалоговых окон посылает некоторые сообщения специальной callback-функции, называемой процедурой диалогового окна, которая имеет следующий формат:

function        DlgProc _
(byval  hDlg as HWND
uMsg as UINT, _
byval wparam as WPARAM, byval lparam as LPARAM) as BOOL

Процедура диалогового окна очень похожа на процедуру окна, если не считать тип возращаемого значения - TRUE/FALSE, вместо обычных LRESULT. Внутренний менеджер диалоговых окон внутри Windows - истинная процедура для диалоговых окон. Она вызывает нашу процедуру диалоговых окон, передавая некоторые из полученных сообщений. Поэтому главное правило следующее: если наша процедура диалогового окна обрабатывает сообщение, она должна вернуть TRUE и если она не обрабатывает сообщение, тогда она должна вернуть FALSE. Заметьте, что процедура диалогового окна не передает сообщения функции DefWindowProc, так как это не настоящая процедура окна.

Диалоговое окно можно использовать в двух целях. Вы можете использовать ее как основное окно или как вспомогательное для получения информации, вводимой пользователем. В этом туториале мы изучим первый вариант.

"Использование диалогового окна как основное окно" можно понимать двояко.

• Вы можете использовать шаблон диалогового окна как шаблон класса, который вы регистрируете с помощью функции RegisterClassEx. В этом случае, диалоговое окно ведет себя как "нормальное": оно получает сообщения через процедуру окна, на которую ссылается lрfnWndProc, а не через процедуру диалогового окна.
Выгода данного подхода состоит в том, что вы не должны самостоятельно создавать дочерние элементы управления, Windows создает их во время создания диалогового окна. Также Windows берет на себя логику нажатий на клавиши (Tab и т.д.). Плюс вы можете указать курсор и иконку вашего окна в структуре класса окна.

• Ваша программа создает диалоговое окно без создания родительского окна. Этот подход делает цикл сообщений ненужным, так как сообщения шлются напрямую процедуре диалогового окна. Вам даже не нужно регистрировать класс окна!

Похоже, что этот туториал будет довольно долгим.

Пример:

файл dialog.bas

Код:

' диалоговое окно как основное
#include "windows.bi"
#include "l10_dialog.bi"

declare function WinMain ( byval hInst as HINSTANCE, _
byval hPrevInst as HINSTANCE, _
  byval szCmdLine as LPSTR, _
  byval iCmdShow as integer ) as integer

' начало программы

dim shared as zString * 512 buffer 'буффер для editboxа

end WinMain(GetModuleHandle( NULL ),NULL,GetCommandLine() , SW_SHOWNORMAL ) ' вызвать основную функцию
' здесь заканчивается программа

' процедура окна
function  WndProc _
(byval hwnd as HWND, _ ' хэндл окна
byval uMsg as UINT, _ ' сообщение
byval wParam as WPARAM, _ ' дополнительный  параметр сообщений
byval lParam as LPARAM) as LRESULT ' дополнительный параметр сообщений

function = 0
select case uMsg  'начинаем обработку сообщений
case WM_DESTROY ' если пользователь закрывает окно
PostQuitMessage(0) ' выходим из программы
exit function
case WM_COMMAND ' если получили сообщение WM_COMMAND
if lParam = 0 then ' если lParam = 0, значит идет сообщение от меню
select case loword(wParam)  ' начинаем обрабатывать элементы меню
case IDM_GETTEXT

' прочитаем текст из editboxа в буфер
GetDlgItemText _
(hwnd, _ ' хэндл диалога
IDC_EDIT, _ ' идентификатор editboxа
@buffer, _ ' указатель на буфер
512) ' число прочитанных байт  

' выведем в Message Box
MessageBox(NULL,@buffer,"Our First Dialog Box",MB_OK)
case IDM_CLEAR
    
    ' очистим editbox
SetDlgItemText _
    (hwnd, _ ' хэндл диалога
    IDC_EDIT, _ ' хэндл editboxа
    NULL) ' пустая строка
case IDM_EXIT
        DestroyWindow(hwnd) ' разрушим окно и выдем из программы
        end select
    end if
    
    if hiword(wparam) = BN_CLICKED then ' если кликают кнопки
    select case loword(wParam) ' продолжаем проверять идентификаторы
case IDC_BUTTON ' если сообщение нашей кнопки

'запишем в editbox тестовую строку
SetDlgItemText _
(hwnd, _ ' хэндл диалога
IDC_EDIT, _ ' идентификатор editboxа
"Wow! I'm in an edit box now") ' тестовая строка
case IDC_EXIT
    
' пошлем сообщение, как будто мы выбрали в менюшке exit
SendMessage _
(hwnd, _ ' хэндл окна
WM_COMMAND, _ ' тип сообщения
IDM_EXIT, _ ' ид меню
0)
end select
end if
end select
function = DefWindowProc(hwnd,uMsg,wParam,lParam) ' Дефаултная функция обработки окна
end function


'функция WinMain
function WinMain _
(byval hInst as HINSTANCE, _ ' хэндл программы
byval hPrevInst as HINSTANCE, _ 'в win32 всегда 0
byval szCmdLine as LPSTR, _  'указатель на командную строку
byval iCmdShow as integer ) as integer  ' состояние окна при первом появлении

dim wc as WNDCLASSEX ' структура параметров окна
dim wMsg as MSG  ' структура сообщений
 dim hDlg as HWND ' хэндл диалога
 
 'структура класса окна wc
with wc ' заполняем структуру wc
.cbSize = SIZEOF( WNDCLASSEX )  ' размер структуры WNDCLASSEX
.style = CS_HREDRAW or CS_VREDRAW  ' Стиль окна
.lpfnWndProc = @WndProc ' Адрес процедуры окна WndProc
.cbClsExtra = NULL  ' резервирование  дополнительных байт за концом структуры
.cbWndExtra = DLGWINDOWEXTRA
.hInstance = hInst  ' хэндл модуля
.hbrBackground = cast(HGDIOBJ, COLOR_BTNFACE+1) ' Цвет фона
.lpszMenuName = @"MyMenu" ' хэндл меню
.lpszClassName = @"DLGCLASS" ' имя класса окна
.hIcon = LoadIcon( NULL,IDI_APPLICATION ) ' Хэндл иконки
.hIconSm = .hIcon 'Хэндл маленькой иконки
.hCursor = LoadCursor( NULL,IDC_ARROW) ' Хэндл курсора
end with

' регистрация нашего класса окна
if(RegisterClassEx(@wc) = FALSE) then
MessageBox(0,"Не могу зарегистрировать класс окна","Ошибка",0)
end 1
end if

' Создадим диалог
hDlg = CreateDialogParam _
(hInst, _ ' хэндл модуля
"MyDialog", _ ' id dialoga
NULL,NULL,NULL)
if hDlg = 0 then
    messagebox(0,"Не могу создать диалог","ошибка",0)
end 2
end if
ShowWindow(hDlg,iCmdShow) ' отобразить наше окно на десктопе
UpdateWindow( hDlg) ' обновить клиентскую область

' получим дескриптор editboxа и установим фокус в editbox
SetFocus(GetDlgItem _
(hDlg,_ ' хэндл диалога
IDC_EDIT)) ' id editboxа

while( GetMessage( @wMsg, NULL, 0, 0 ) <> FALSE )  'цикл сообщений
if IsDialogMessage(hDlg, @wMsg) = FALSE then
TranslateMessage( @wMsg )
DispatchMessage( @wMsg )
end if
wend
function = wMsg.wParam
end function

Dialog.rc

Код:

#include "resource.h"

MyDialog DIALOG 10, 10, 205, 60
STYLE 0x0004 | DS_CENTER | WS_CAPTION | WS_MINIMIZEBOX |
WS_SYSMENU | WS_VISIBLE | WS_OVERLAPPED | DS_MODALFRAME | DS_3DLOOK
CAPTION "Our First Dialog Box"
CLASS "DLGCLASS"
{
EDITTEXT         IDC_EDIT,   15,17,111,13, ES_AUTOHSCROLL | ES_LEFT
DEFPUSHBUTTON   "Say Hello", IDC_BUTTON,    141,10,52,13
PUSHBUTTON      "E&xit", IDC_EXIT,  141,26,52,13, WS_GROUP
}

MyMenu  MENU
{
POPUP "Test Controls"
{
MENUITEM "Get Text", IDM_GETTEXT
MENUITEM "Clear Text", IDM_CLEAR
MENUITEM "", , 0x0800 /*MFT_SEPARATOR*/
MENUITEM "E&xit", IDM_EXIT
}
}


Последний раз редактировалось: electrik (Вт Май 23, 2017 5:50 pm), всего редактировалось 1 раз(а)

electrik

Сообщения : 391
Дата регистрации : 2008-09-02
Возраст : 37
Откуда : галактика Млечный путь, система Солнечная, планета Земля, страна россия, город Санкт Петербург

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: платформа Win32 - Туториалы Iczelion'a на русском, адаптированные для FreeBasic. Урок 10 - Диалоговое окно как основное

Сообщение  electrik в Пн Июн 29, 2009 5:47 pm

Win32 API. Урок 10. Диалоговое окно как основное - продолжение


Анализ:

Давайте проанализируем первый пример.
Этот пример показывает, как зарегистрировать диалоговый шаблон как класс окна и создает "окно" из этого класса. Это упрощает вашу программу, так как вам не нужно создавать дочерние контролы самостоятельно.

Давайте проанализируем шаблон диалогового окна.

MyDialog DIALOG 10, 10, 205, 60

Объявление имя диалога, в данном случае - "MyDialog", за которым следует ключевое слово "DIALOG". Следующие четыре номера - это x, y, ширина и высота диалогового окна в специальных единицах (не в пикселях).

STYLE 0x0004 | DS_CENTER | WS_CAPTION | WS_MINIMIZEBOX |
WS_SYSMENU | WS_VISIBLE | WS_OVERLAPPED | DS_MODALFRAME | DS_3DLOOK

Объявление стилей диалогового окна.

CAPTION "Our First Dialog Box"

Это текст, который появится в title bar'е.

CLASS "DLGCLASS"

Это ключевая строка. Ключевое слово 'CLASS' позволяет нам использовать шаблон диалогового окна в качестве класса окна. Следующее слово - это имя "класса окна".

{
EDITTEXT IDC_EDIT, 15,17,111,13, ES_AUTOHSCROLL | ES_LEFT
DEFPUSHBUTTON "Say Hello", IDC_BUTTON, 141,10,52,13
PUSHBUTTON "E&xit", IDC_EXIT, 141,26,52,13
}

Данный блок определяет дочерние элементы управления в диалоговом окне. Они определены между фигурными скобками { }. Общий синтаксис таков:

control-type "text" ,controlID, x, y, width, height [,styles]

control-type'ы - это константы компилятора ресурсов, вам нужно свериться с руководством.

Теперь мы углубляемся непосредственно в код. Интересующая нас часть находится в структуре класса окна.

.cbWndExtra = DLGWINDOWEXTRA
.lpszClassName = @"DLGCLASS"

Обычно этот параметр оставляется равным нулю, но если мы хотим зарегистрировать шаблон диалогового окна как класс окна, мы должны установить этот параметр равным DLGWINDOWEXTRA. Заметьте, что имя класса должно совпадать с именем, что определено в шаблоне диалогового окна. Остающиеся параметры инициализируются как обычно. После того, как вы заполните структуру класса окна, зарегистрируйте ее с помощью RegisterClassEx. Звучит знакомо. Точно также вы регистрируете
обычный класс окна.

' Создадим диалог
hDlg = CreateDialogParam _
(hInst, _
"MyDialog", _
NULL,NULL,NULL)

После регистрации "класса окна", мы создаем наше диалоговое окно. В этом примере я создал его как независимое диалоговое окно функцией CreateDialogParam.
Эта функция получает 5 параметров, но вам нужно заполнить только первые два: хэндл процесса и указатель на имя шаблона диалогового окна. Заметьте, что второй параметр - это не указатель на имя класса.

В этот момент, диалоговое окно и его дочерние элементы управления создаются Windows. Ваша процедура окна получит сообщение WM_CREATE как обычно.

SetFocus(GetDlgItem _
(hDlg,_
IDC_EDIT))

После того, как диалоговое окно создано, я хочу установить фокус ввода на edit control. Если я помещу соответствующий код в секцию WM_CREATE, вызов GetDlgItem провалится, так как дочерние окна еще не созданы. Единственный путь сделать это - вызвать эту функцию после того, как диалоговое окно и все его дочерние окна будут созданы. Поэтому я помещаю данные две линии после вызова UpdateWindow. Функция GetDlgItem получает ID контрола и возвращает соответствующий хэндл окна. Так вы можете получить хэндл окна, если вы знаете его control ID.

if IsDialogMessage(hDlg, @wMsg) = FALSE then
TranslateMessage( @wMsg )
DispatchMessage( @wMsg )
end if

Программа входит в цикл сообщений и перед тем, как мы транслируем и передаем сообщения, мы вызываем функцию IsDialogMessage, чтобы позволить менеджеру диалоговых сообщений обрабатывать логику сообщений за нас. Если эта функция возвращает TRUE, это значит, что сообщение сделано для диалогового окна и обрабатывается менеджером диалоговых сообщений. Отметьте другое отличие от предыдущего туториала. Когда процедура окна хочет получить текст с edit контрола, она вызывает функцию GetDlgItemText, вместо функции GetWindowText. GetDlgItemText принимает ID контрола вместо хэндла окна. Это делает вызов проще в том случае, если вы используете диалоговое окно.

Теперь давайте перейдем ко второму подходу использования диалогового окна как основного окна. В следующем примере, я создам програмно-модальное диалоговое окно. Вы не увидите цикл сообщений или процедуру окна, потому что они не нужны!

Код:

'програмно-модальное диалоговое окно
#include "windows.bi"
#include "dialog_p2.bi"

declare  Function DlgProc (byval hwnd as HWND, byval uMsg as UINT, _
byval wparam as WPARAM, byval lparam as LPARAM) as BOOL

dim shared hModule as HINSTANCE ' хэндл модуля(программы)
dim shared as zstring * 512 buffer ' буфер для editboxа
hModule = GetModuleHandle(NULL) ' получим хэндл программы
'создадим диалог
end DialogBoxParam _
(hModule, _ ' хэндл программы
"MyDialog", _ ' идентификатор диалога
NULL, _
@DlgProc, _ ' указатель на DlgProc
NULL)

 Function DlgProc (byval hwnd as HWND, byval uMsg as UINT, _
byval wparam as WPARAM, byval lparam as LPARAM) as BOOL
select case uMsg
case WM_INITDIALOG ' если диалог инициализируется
   
    ' получим дискриптор editboxа и установим фокус в editbox
    SetFocus(GetDlgItem _
    (hWnd, _ ' хэндл диалога
IDC_EDIT)) ' идентификатор editboxа
case WM_CLOSE ' если сообщение о закрытии окна

' пошлем сообщение, как будто мы выбрали в меню exit
SendMessage _
(hWnd, _ ' хэндл диалога
WM_COMMAND, _ ' тип сообщения
IDM_EXIT, _ ' идентификатор меню
0)
case WM_COMMAND
    if lParam = 0 then ' если равно 0, значит идут сообщения от меню
                select case loword(wParam) ' начинаем обрабатывать сообщения от меню
        case IDM_GETTEXT

' прочитаем текст из editboxа в буфер
GetDlgItemText _
(hWnd, _ ' хэндл диалога
IDC_EDIT, _ ' идентификатор editboxа
@buffer, _ ' указатель на буфер
512) ' число прочитанных байт

' выведем буфер в MessageBox
MessageBox(NULL,@buffer,"Our Second Dialog Box",MB_OK)
case IDM_CLEAR

' очистим editbox
SetDlgItemText _
(hWnd, _ ' хэндл диалога
IDC_EDIT, _ ' идентификатор editboxа
NULL) ' пустая строка
case IDM_EXIT

' закроем диалог функцией EndDialog
    EndDialog _
(hWnd, _ ' хэндл диалога
NULL)
end select
end if

if hiword(wParam) = BN_CLICKED then ' если кликают кнопки
    select case loword(wParam) ' продолжаем проверять идентификаторы
case IDC_BUTTON
   
    ' запишем в editbox тестовую строку
    SetDlgItemText _
    (hWnd, _ ' хэндл диалога
IDC_EDIT, _ ' идентификатор editboxа
"Wow! I'm in an edit box now") ' строка записываемая в editbox
case IDC_EXIT

' пошлем сообщение, как будто мы выбрали в меню exit
SendMessage(hWnd, _ ' хэндл диалога
WM_COMMAND, _ ' тип сообщения
IDM_EXIT, _ ' идентификатор меню
0)
end select
end if
case else
    function = FALSE
exit function
end select
function =  TRUE
end function

файл dialog_p2.bi

Код:

#define IDC_EDIT                                      3000
#define IDC_BUTTON                                3001
#define IDC_EXIT                                      3002
#define IDR_MENU1                                  3003
#define IDM_GETTEXT                              32000
#define IDM_CLEAR                                  32001
#define IDM_EXIT                                      32003

файл dialog_p2.rc

Код:

#include "dialog_p2.bi"
MyDialog DIALOG 10, 10, 205, 60
STYLE 0x0004 | DS_CENTER | WS_CAPTION | WS_MINIMIZEBOX |
WS_SYSMENU | WS_VISIBLE | WS_OVERLAPPED | DS_MODALFRAME | DS_3DLOOK
CAPTION "Our Second Dialog Box"

MENU IDR_MENU1
BEGIN
EDITTEXT        IDC_EDIT,  15,17,111,13, ES_AUTOHSCROLL | ES_LEFT
DEFPUSHBUTTON  "Say Hello", IDC_BUTTON,    141,10,52,13
PUSHBUTTON      "E&xit", IDC_EXIT,  141,26,52,13
END

IDR_MENU1  MENU
BEGIN
POPUP "Test Controls"
BEGIN
MENUITEM "Get Text", IDM_GETTEXT
MENUITEM "Clear Text", IDM_CLEAR
MENUITEM "", , 0x0800 /*MFT_SEPARATOR*/
MENUITEM "E&xit", IDM_EXIT
END
END
Анализ:

Function DlgProc (byval hwnd as HWND, byval uMsg as UINT, _
byval wparam as WPARAM, byval lparam as LPARAM) as BOOL

Мы объявляем прототип функции для DlgProc, так что мы можем ссылаться на нее оператором @:

end DialogBoxParam _
(hModule, _ '
"MyDialog", _
NULL, _
@DlgProc, _
NULL)

В вышеприведенной строке вызывается функция DialogBoxParam, которая получает 5 параметров: хэндл процесса, имя шаблона диалогового окна, хэндл родительского окна, адрес процедуры диалогового окна и специальные данные для диалогового окна. DialogBoxParam создает модальное диалоговое окно. Она не возвращается, пока диалоговое окно не будет уничтожено.

case WM_INITDIALOG
SetFocus(GetDlgItem _
(hWnd, _
IDC_EDIT))
case WM_CLOSE
SendMessage _
(hWnd, _
WM_COMMAND, _
IDM_EXIT, _
0)

Процедура диалогового окна выглядит как процедура окна, не считая того, что она не получает сообщение WM_CREATE. Первое сообщение, которое она получает- это WM_INITDIALOG. Обычно вы помещаете здесь инициализационный код. Заметьте, что вы должны вернуть значение TRUE, если вы обрабатываете это сообщение.

Внутренний менеджер диалогового окна не посылает нашей процедуре сообщение WM_DESTROY, а вот WM_CLOSE шлет. Поэтому если мы хотим отреагировать на то, что юзер нажимает кнопку закрытия на нашем диалоговом окне, мы должны обработать сообщение WM_CLOSE. В нашем примере мы посылаем сообщение WM_CLOSE со значением IDM_EXIT в wParam. Это произведет тот же эффект, что и выбор пункта 'Exit' в меню. EndDialog вызывается в ответ на IDM_EXIT.

Обработка сообщений WM_COMMAND остается такой же.

Когда вы хотите уничтожить диалоговое окно, единственный путь - это вызов функции EndDialog. Не пробуйте DestroyWindow! EndDialog не уничтожает диалоговое окно немедленно. Она только устанавливает флаг для внутреннего менеджера диалогового окна и продолжает выполнять следующие инструкции.

Теперь давайте изучим файл ресурсов. Заметное изменение - это то, что вместо использования текстовой строки в качестве имени меню, мы используем значение IDR_MENU1. Это необходимо, если вы хотите прикрепить меню к диалоговому окну, созданному DialogBoxParam'ом. Заметьте, что в шаблоне диалогового окна вы должны добавить ключевое слово 'MENU', за которым будет следовать ID ресурса меню.

различие между двумя примерами в этом туториале, которое вы можете легко заметить - это отсутствие иконки в последнем примере. Тем не менее, вы можете установить иконку, послав сообщение WM_SETICON диалоговому окну во время обработки WM_INITDIALOG.

[C] Iczelion, пер. Aquila.

electrik

Сообщения : 391
Дата регистрации : 2008-09-02
Возраст : 37
Откуда : галактика Млечный путь, система Солнечная, планета Земля, страна россия, город Санкт Петербург

Посмотреть профиль

Вернуться к началу Перейти вниз

Предыдущая тема Следующая тема Вернуться к началу

- Похожие темы

 
Права доступа к этому форуму:
Вы не можете отвечать на сообщения