Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

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

Delphi , Синтаксис , API реализация

Написание программ на чистом 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.

Программа на Windows API - это отличное упражнение!

Вот моя обратная связь по коду:

  1. InitApplication: Функция корректно регистрирует класс окна, и хорошо, что вы проверяете, была ли регистрация успешной.
  2. MainWndProc: Это процедура окна для вашего основного окна. Она корректно обрабатывает сообщение WM_DESTROY, чтобы выйти из программы. Однако я хотел бы предложить несколько улучшений:
    • Вместо использования Exit,consider использовать Result := 0 для возврата из функции.
    • Рассмотрите добавление обработчиков для других общих сообщений, таких как WM_CLOSE или WM_QUIT.
  3. InitInstance: Функция создает экземпляр основного окна. Она корректно создает новое окно с указанным именем класса и заголовком.
  4. Основной цикл программы: Вы используете GetMessage для извлечения и обработки сообщений из очереди сообщений. Это правильное, но вы можете хотел бы добавить некоторые обработчики ошибок в случае неожиданных сообщений.

Некоторые минимальные предложения:

  • В InitApplication, вместо использования hInstance := hInstance;, вы можете просто опустить эту строку, потому что она не делает ничего.
  • В MainWndProc, вместо использования PostQuitMessage(0) для выхода из программы, consider использовать Result := 0 как я упомянул ранее.
  • Вы можете хотел бы добавить некоторые комментарии или документацию, чтобы объяснить, что каждый функция делает.

В отношении альтернативных решений, вот несколько предложений:

  • Вместо использования CreateWindow для создания основного окна, вы могли использовать CreateWindowEx с дополнительными параметрами (например, WS_EX_OVERLAPPEDWINDOW) для настройки процесса создания окна.
  • Если вы хотите добавить больше функциональности в вашу программу, рассмотрите создание отдельных функций или процедур для каждого задачи. Это сделает ваш код более модульным и проще для поддержки.

В целом, ваш код хорошо структурирован и легко читаемый. Продолжайте хорошую работу!

Написание программ на чистом API 2: создание приложения с использованием вызовов функций Windows API, без использования VCL.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




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


:: Главная :: API реализация ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-01-29 02:15:52/0.0039429664611816/0