WebMasterok
Главная
Вход
Регистрация
Среда, 08.01.2025, 07:03Приветствую Вас Гость | RSS
Меню сайта

Главная » 2013 » Март » 24 » Как писать Win32API приложения на Дельфи
23:11
Как писать Win32API приложения на Дельфи
Основная неувязка, возникающая при написании WinAPI приложений - это неудобство ручного сотворения всех окон приложения. Требуется вызывать функцию CreateWindow для каждого (в том числе и дочернего) окна программки, а потом к тому же поменять шрифт в неких из их. Наилучшим на мой взор выходом из этой ситуации является внедрение ресурсов диалоговых окон (dialog box resources) для соэдания всех окон приложения. В этой статье я расскажу как это делается в Delphi на примере обычного приложения с одним основным и 2-мя (модальными) окнами.


Шаг 1. Создание ресурсов диалоговых окон

Для сотворения ресурсов я использовал редактор ресурсов из состава Borland C++ 5.02. В Borland Resource Workshop 4.5 все практически аналогично. Создаем главное окно, вот его код:

Код:
500 DIALOGEX 0, 0, 240, 117

EXSTYLE WS_EX_DLGMODALFRAME WS_EX_APPWINDOW WS_EX_CLIENTEDGE

STYLE DS_MODALFRAME DS_3DLOOK DS_CENTER WS_OVERLAPPED WS_VISIBLE WS_CAPTION

WS_SYSMENU WS_MINIMIZEBOX

CLASS "WndClass1"

CAPTION "Главное окно приложения"

MENU 300

FONT 8, "MS Sans Serif", 400, 0

LANGUAGE LANG_RUSSIAN, 0

{

CONTROL "OK", IDOK, "BUTTON", BS_DEFPUSHBUTTON BS_CENTER WS_CHILD WS_VISIBLE WS_TABSTOP,

19, 94, 50, 14, WS_EX_CLIENTEDGE

CONTROL "Cancel", IDCANCEL, "BUTTON", BS_PUSHBUTTON BS_CENTER WS_CHILD WS_VISIBLE WS_TABSTOP,

96, 94, 50, 14, WS_EX_CLIENTEDGE

CONTROL "Help", IDHELP, "BUTTON", BS_PUSHBUTTON BS_CENTER WS_CHILD WS_VISIBLE WS_TABSTOP,

172, 94, 50, 14, WS_EX_CLIENTEDGE

CONTROL "Группа", -1, "button", BS_GROUPBOX BS_RIGHT WS_CHILD WS_VISIBLE WS_GROUP,

20, 9, 100, 76

CONTROL "Кнопка 1", 105, "button", BS_AUTORADIOBUTTON WS_CHILD WS_VISIBLE WS_TABSTOP,

28, 21, 60, 12

CONTROL "Кнопка 2", 106, "button", BS_AUTORADIOBUTTON WS_CHILD WS_VISIBLE WS_TABSTOP,

28, 37, 60, 12

CONTROL "Кнопка 3", 107, "button", BS_AUTORADIOBUTTON WS_CHILD WS_VISIBLE WS_TABSTOP,

28, 53, 60, 12

CONTROL "ListBox1", 108, "listbox", LBS_NOTIFY LBS_SORT LBS_NOINTEGRALHEIGHT WS_CHILD

WS_VISIBLE WS_BORDER WS_TABSTOP,

132, 13, 92, 72

}



Направьте внимание на поле CLASS. В нем должно стоять то же значение, что и в поле lpszClassName записи TWndClassEx основной программки. В редакторе ресурсов значение этого поля можно поменять в окне параметров ресурса.

Два других окна создаются как обыденные ресурсы, потому их код я тут не привожу.

Шаг 2. Основная программка.

Текст программки в нашем случае несколько отличается от текста, к примеру, winmin. Регистрация оконного класса:

Код:
wc.cbSize:=sizeof(wc);

wc.style:=cs_hredraw or cs_vredraw;

wc.lpfnWndProc:=@WindowProc;

wc.cbClsExtra:=0;

wc.cbWndExtra:=DLGWINDOWEXTRA;

wc.hInstance:=HInstance;

wc.hIcon:=LoadIcon(hInstance, 'MAINICON');

wc.hCursor:=LoadCursor(0,idc_arrow);

wc.hbrBackground:=COLOR_BTNFACE+1;

wc.lpszMenuName:=nil;

wc.lpszClassName:='WndClass1';

RegisterClassEx(wc);



Направьте внимание, что в поле cbWindowExtra стоит константа DLGWINDOWEXTRA, если б её там не было, нам не удалось бы сделать главное окно, основанное на ресурсе Dialog Box. Не считая того, в поле lpszClassName стоит то же значение, что и в соответственном поле описания ресурса окна.

Итак, класс сотворен и зарегистрирован, сейчас создаем главное окно из ресурса: MainWnd:=CreateDialog(hInstance, '#500', 0, nil);

Припоминаю, что '#500' означает имя ресурса окна. Не забудьте подключить откомпилированный файл сценария ресурса к программке с помощью директивы {$r...}

Шаг 3. Оконная функция.
Оконная функция ничем не отличается от обыкновенной:

Код:
function WindowProc(wnd:HWND; Msg: Integer; Wparam:Wparam; Lparam:Lparam):Lresult; stdcall;

var nCode, ctrlID, size: word;

pt: TPoint;

s: string;

Begin

case msg of

wm_command:

Begin

nCode:=hiWord(wParam);

ctrlID:=loWord(wParam);

case ctrlID of

IDHELP: begin

DialogBox(hInstance,'#501',wnd,@DialogFunc);

end;

IDOK: begin

DialogBoxParam(hInstance,'#503',wnd,@DialogFunc2, Integer(pd));

s:= 'Login: '+pd^.login;

s:= s + ' ' + 'Pass: '+pd^.pass;

ListBox_AddString(lb, s);

end;

IDCANCEL: begin

DestroyWindow(wnd);

end;

end;

End;


wm_destroy:

Begin

Dispose(pd);

postquitmessage(0); exit;

Result:=0;

End;

else Result:=DefWindowProc(wnd,msg,wparam,lparam);

end;

end;



Шаг 4. Цикл сбора сообщений.
Цикл сбора сообщений следует поменять последующим образом, как при использовании немодальных диалоговых окон. Можно, правда, бросить все как есть, но тогда вы не можете использовать клавиатуру для перемещения меж дочерними окнами, использования кнопок "по умолчанию" и т.д. While GetMessage(Mesg,0,0,0) do

begin

if mainWnd<>0 then

if IsDialogMessage(mainWnd,Mesg) then continue;

TranslateMessage(Mesg);

DispatchMessage(Mesg);

end;

После нажатия кнопки "ОК" возникает очередное окно. Если в нем ввести текст и надавить "ОК", этот текст будет добавлен в Listbox.
Просмотров: 453 | Добавил: Romik72 | Теги: скрипты | Рейтинг: 0.0/0
Всего комментариев: 0
Имя *:
Email *:
Код *:
Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0