Оригинальный DVD-ROM: eXeL@B DVD !
eXeL@B ВИДЕОКУРС !

ВИДЕОКУРС ВЗЛОМ
выпущен 2 сентября!


УЗНАТЬ БОЛЬШЕ >>
Домой | Статьи | RAR-cтатьи | FAQ | Форум | Скачать | Видеокурс
Новичку | Ссылки | Программирование | Интервью | Архив | Связь

БОЛЬШОЙ FAQ ПО DELPHI



Написание программ на чистом API 2

В этом выпуске мы попробуем написать с Вами программу, которая не будет пользоваться VCL, а будет использовать вызовы функций Windows API. Приложения такого типа нужны, когда размер исполняемого файла является критичным. Например, в инсталяторах, деинсталяторах, самораспаковывающихся архивах и т.п. В крайнем случае, для того чтобы посмотреть какую работу выполняет за нас VCL, и что из себя представляет Windows-программа. На самом деле все очень просто...

Для этого нам необходимо:


 // 1. Зарегистрировать класс окна для окна главной формы.
 
 function InitApplication: Boolean;
 var
   wcx: TWndClass;
 begin
 //Заполняем структуру TWndClass
     // перерисовываем, если размер изменяется
     wcx.style := CS_HREDRAW or CS_VREDRAW;
     // адрес оконной процедуры
     wcx.lpfnWndProc := @MainWndProc;
     wcx.cbClsExtra := 0;
     wcx.cbWndExtra := 0;
     // handle to instance
     wcx.hInstance := hInstance;
     // загружаем стандандартную иконку
     wcx.hIcon := LoadIcon(0, IDI_APPLICATION);
     // загружаем стандартный курсор
     wcx.hCursor := LoadCursor(0, IDC_ARROW);
     // делаем светло-cерый фон
     wcx.hbrBackground := COLOR_WINDOW;
     // пока нет главного меню
     wcx.lpszMenuName :=  nil;
     // имя класса окна
     wcx.lpszClassName := PChar(WinName);
 
     // Регистрируем наш класс окна.
     Result := RegisterClass(wcx) <> 0;
 end;
 
 // 2. Написать подпрограмму обработки оконных сообщений.
 
 function MainWndProc(Window: HWnd; AMessage, WParam,
                     LParam: Longint): Longint; stdcall; export;
 begin
   //подпрограмма обработки сообщений
   case AMessage of
     WM_DESTROY: begin
       PostQuitMessage(0);
       Exit;
     end;
     else
        Result := DefWindowProc(Window, AMessage, WParam, LParam);
   end;
 end;
 
 // 3. Создать главное окно приложения.
 
 function InitInstance: HWND;
 begin
   // Создаем главное окно.
   Result := CreateWindow(
    // имя класса окна
    PChar(WinName),
    // заголовок
    'Small program',
    // стандартный стиль окна
    WS_OVERLAPPEDWINDOW,
    // стандартные горизонтальное, вертикальное положение, ширина и высота
    Integer(CW_USEDEFAULT),
    Integer(CW_USEDEFAULT),
    Integer(CW_USEDEFAULT),
    Integer(CW_USEDEFAULT),
    0,//нет родительского окна
    0,//нет меню
    hInstance, // handle to application instance
    nil);      // no window-creation data
 end;
 
 // 4. Написать тело программы.
 
 var
   hwndMain: HWND;
   AMessage: msg;
 begin
     if (not InitApplication) then
     begin
       MessageBox(0, 'Ошибка регистрации окна', nil, mb_Ok);
       Exit;
     end;
     hwndMain := InitInstance;
     if (hwndMain = 0) then
     begin
       MessageBox(0, 'Ошибка создания окна', nil, mb_Ok);
       Exit;
     end
     else
     begin
       // Показываем окно и посылаем сообщение WM_PAINT оконной процедуре
       ShowWindow(hwndMain, CmdShow);
       UpdateWindow(hwndMain);
     end;
     while (GetMessage(AMessage, 0, 0, 0)) do
     begin
       //Запускаем цикл обработки сообщений
       TranslateMessage(AMessage);
       DispatchMessage(AMessage);
     end;
     Halt(AMessage.wParam);
 end.
 // 5. Запустить программу на исполнение. ;)
 

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

Здесь находится полный текст программы.


 program SmallPrg;
 
 uses Windows,  Messages;
 
 const
   WinName = 'MainWClass';
 
 function MainWndProc(Window: HWnd; AMessage, WParam,
                     LParam: Longint): Longint; stdcall; export;
 begin
   //подпрограмма обработки сообщений
   case AMessage of
     WM_DESTROY: begin
       PostQuitMessage(0);
       Exit;
     end;
     else
        Result := DefWindowProc(Window, AMessage, WParam, LParam);
   end;
 end;
 
 function InitApplication: Boolean;
 var
   wcx: TWndClass;
 begin
 //Заполняем структуру TWndClass
     // перерисовываем, если размер изменяется
     wcx.style := CS_HREDRAW or CS_VREDRAW;
     // адрес оконной процедуры
     wcx.lpfnWndProc := @MainWndProc;
     wcx.cbClsExtra := 0;
     wcx.cbWndExtra := 0;
     // handle to instance
     wcx.hInstance := hInstance;
     // загружаем стандандартную иконку
     wcx.hIcon := LoadIcon(0, IDI_APPLICATION);
     // загружаем стандартный курсор
     wcx.hCursor := LoadCursor(0, IDC_ARROW);
     // делаем светло-cерый фон
     wcx.hbrBackground := COLOR_WINDOW;
     // пока нет главного меню
     wcx.lpszMenuName :=  nil;
     // имя класса окна
     wcx.lpszClassName := PChar(WinName);
 
     // Регистрируем наш класс окна.
     Result := RegisterClass(wcx) <> 0;
 end;
 
 function InitInstance: HWND;
 begin
   // Создаем главное окно.
   Result := CreateWindow(
    // имя класса окна
    PChar(WinName),
    // заголовок
    'Small program',
    // стандартный стиль окна
    WS_OVERLAPPEDWINDOW,
    // стандартные горизонтальное, вертикальное положение, ширина и высота
    Integer(CW_USEDEFAULT),
    Integer(CW_USEDEFAULT),
    Integer(CW_USEDEFAULT),
    Integer(CW_USEDEFAULT),
    0,//нет родительского окна
    0,//нет меню
    hInstance, // handle to application instance
    nil);      // no window-creation data
 end;
 
 var
   hwndMain: HWND;
   AMessage: msg;
 begin
     if (not InitApplication) then
     begin
       MessageBox(0, 'Ошибка регистрации окна', nil, mb_Ok);
       Exit;
     end;
     hwndMain := InitInstance;
     if (hwndMain = 0) then
     begin
       MessageBox(0, 'Ошибка создания окна', nil, mb_Ok);
       Exit;
     end
     else
     begin
       // Показываем окно и посылаем сообщение WM_PAINT оконной процедуре
       ShowWindow(hwndMain, CmdShow);
       UpdateWindow(hwndMain);
     end;
     while (GetMessage(AMessage, 0, 0, 0)) do
     begin
       //Запускаем цикл обработки сообщений
       TranslateMessage(AMessage);
       DispatchMessage(AMessage);
     end;
     Halt(AMessage.wParam);
 end.
 




<< ВЕРНУТЬСЯ В ОГЛАВЛЕНИЕ



Материалы находятся на сайте https://exelab.ru/pro/



Оригинальный DVD-ROM: eXeL@B DVD !


Вы находитесь на EXELAB.rU
Проект ReactOS