Понедельник, 29.04.2024
Королевство Delphi
Главное меню
Статьи
Наш опрос
Как часто ви на этот сайт заходите?
Всего ответов: 159
Статистика
Онлайн всего: 1
Гостей: 1
Пользователей: 0
Форма входа
Главная » Статьи » Система » WinAPI

Мегабайты отдыхают
  • Постановка задачи.
  • Пример решения с исходным кодом.
  • Выгода при использовании данного решения.
  • Заключение.

1. Постановка задачи

Данный способ позволяет значительно экономить ресурсы компьютера. Кроме того, все знают, что минимальный размер готового проекта с (формой) на делфи составляет 250-300 Кб. А если там не одна форма, а несколько, то проекты зачастую разрастаются до 3-4 и более Мб. Я же научу вас создавать приложения с формами, но весить такие проекты будут по 15-20 Кб.

Данный способ требует отказа от использования всех VCL, т.е. все придеться делать ручками. Он основан на использовании функции CreateWindow, которая может создавать любое окно в соответствии с заданными параметрами.
Интересно?

Читайте дальше!

2.Пример решения с исходным кодом

Создание компонентов данным методом требует от программиста большого труда и терпения, т.к. теперь придется забыть о благосклонности делфи, делающей за нас все шаблоны функций, заготовки модулей и прочую "черную работу". Теперь, как я уже сказал выше, все придется писать нам самим, вручную ;)

Итак, для начала создадим проект в делфи, нажав File->New->Application. Поскольку мы договорились не использовать формы, то делаем так: Project->Remove From Project, выбираем Unit1 и нажимаем кнопку ОК. Затем нужно вывести на экран код программы: Project->View Source. Открылся текстовый редактор с кодом программы. Из секции uses удаляем все, вписываем туда windows, messages;
Затем удаляем

begin
 Application.Initialize;
 Application.CreateForm(TForm1, Form1);
 Application.Run;
end. 

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

program Project1;

uses windows, messages;

{$R *.res}

var
 WinClass : TWndClass; //переменная класса TWndClass для создания главного окна
 hInst : HWND; //хандлер приложения
 Handle : HWND; //хандлер
 hMsgBtn : HWND; //Хандлер кнопки
 hMsgEdit : HWND; //Хандлер эдита
 hMsgLabel : HWND; //Хандлер лабы
 hFont : HWND; //Хандлер шрифта
 Msg : TMSG; //Сообщение
 pr_Click : pointer; //Указатель на процедуру

procedure Resize; //Демонстрация изменения размеров и положения компонентов программным способом, если мы изменяем окно
 var Rect:TRect;
begin
 GetWindowRect(Handle,Rect); // Цепляем окошко
 MoveWindow(hMsgEdit,30,90, Rect.Right-Rect.Left-100,22,True); // А тут можно изменить его размеры или положение
end;

procedure ShutDown; // Выключение
begin
 DeleteObject(hFont); //Удаляем шрифты
 UnRegisterClass('Sample Class', hInst); //Удаляем наше окно
 ExitProcess(hInst); // Выходим из проги
end;

procedure Click; // Задача для кнопки
 var Label_Text:PCHAR; // Определяем переменные для текста и его длины
 LText:integer;
begin
 LText:=GetWindowTextLength(hMsgEdit)+1; // Получим длину текста и не забудем его последний символ (+1)
 GetMem(Label_Text,LText); // Выделим память под переменную текста
 GetWindowText(hMsgEdit,Label_Text,LText); //Захватим текст из едит-бокса
 SetWindowText(hMsgLabel,Label_Text); //Назначим текст метке
end;

function ClickProc(hwnd,msg,wparam,lParam:longint):longint;stdcall; // Обработка каждого сообщения, посланного кнопке
begin
 Result:=CallWindowProc(pr_Click,hWnd,Msg,wParam,lParam);
 case Msg of
 WM_KEYDOWN : if wparam=9 then SetFocus(hMsgBtn); //Если юзверь нажал на кнопку, то дадим ей фокус ввода
 end;
end;

function WindowProc(hwnd, msg, wparam, lparam:longint):longint;stdcall; //То же самое для окна
begin
 Result:=DefWindowProc(hwnd,msg,wparam,lparam);
 case Msg of
 WM_SIZE : Resize; // Если изменяем окно, значит, надо его изменить ;)
 WM_COMMAND : if lparam=hMsgBtn then Click; // Если есть нужная команда, выполним процедуру щелчка мыши
 WM_DESTROY : ShutDown; // Если поступило сообщение уничтожения винды, то выполним его.
 end;
end;

begin
 hInst:=GetModuleHandle(nil); // Получим хандлер приложения

 //А теперь задаем свойства окна

 with WinClass do
 begin
 Style:= CS_PARENTDC; //Это - родитель компонентов.
 hIcon:= LoadIcon(hInst,'MAINICON'); //Икона
 lpfnWndProc:= @WindowProc; //Процедура обработки сообщений
 hInstance:= hInst; //Хандлер окна
 hbrBackground:= COLOR_BTNFACE+1; //Цвет окна
 lpszClassName:= 'Sample Class'; //Имя класса
 hCursor:= LoadCursor(0,IDC_ARROW); //Курсор
 end;

 //Регистрируем наш класс
 RegisterClass(WinClass);

 //Собственно создание нашего окна.
 Handle:=CreateWindow(
 'Sample Class', // Зарегистрированное имя класса
 'Маленький проект', // Заголовок окна
 WS_OVERLAPPEDWINDOW or // Стиль окна
 WS_VISIBLE, // Оно видимое
 10, // Левый
 10, // верхний угол окна
 400, // Длина
 300, // Высота
 0, // Хандлер окна
 0, // Хандлер менюшки
 hInst, // Хандлер приложения
 nil
 );

 // Создаем кнопку
 hMsgBtn:=CreateWindow(
 'Button',
 'Message',
 WS_VISIBLE or WS_CHILD or BS_PUSHLIKE or BS_TEXT,
 5,5,65,24,Handle,0,hInst,nil
 );

 // Создаем эдит-бокс
 hMsgEdit:=CreateWindowEx(
 WS_EX_CLIENTEDGE,
 'Edit',
 '',
 WS_VISIBLE or WS_CHILD or ES_LEFT or ES_AUTOHSCROLL,
 30,90,155,24,Handle,0,hInst,nil
 );

 //Создаем label
 hMsgLabel:=CreateWindow(
 'Static',
 '',
 WS_VISIBLE or WS_CHILD or SS_LEFT,
 160,10,170,50,Handle,0,hInst,nil
 );

 //Создаем шрифт
 hFont:=CreateFont(
 -12, // Высота
 0, // Длина
 0, // Угол поворота
 0, // Ориентация
 0, // Жирность
 0, // Курсивность
 0, // Подчеркнутость
 0, // Зачеркнутость
 DEFAULT_CHARSET, // Char Set
 OUT_DEFAULT_PRECIS, // Precision
 CLIP_DEFAULT_PRECIS, // Clipping
 DEFAULT_QUALITY, // Render Quality
 DEFAULT_PITCH or FF_DONTCARE, // Pitch & Family
 'MS Sans Serif' // Имя шрифта
 );


 SendMessage(hMsgBtn,WM_SETFONT,hFont,0); //Назначаем наш шрифт кнопке, эдит-боксу, лабе
 SendMessage(hMsgEdit,WM_SETFONT,hFont,0);
 SendMessage(hMsgLabel,WM_SETFONT,hFont,0);

 //Назначаем кнопке процедуру
 pr_Click:=Pointer(GetWindowLong(hMsgBtn,GWL_WNDPROC));
 SetWindowLong(hMsgBtn,GWL_WNDPROC,Longint(@ClickProc));

 //Установка фокуса ввода на кнопку
 SetFocus(hMsgBtn);

 while(GetMessage(Msg,Handle,0,0))do
 begin
 TranslateMessage(Msg); //Переводим все сообщения...
 DispatchMessage(Msg); //...к черту!!! :))))))))))
 end;


end. 

3.Выгода при использовании данного решения.

Про выгоду я уже сказал выше-данное решение позволяет ОЧЕНЬ сильно сократить размеры исполняемого файла. Где же применять данное решение? не мне вас учить - все зависит от вашей фантазии!

4. Заключение.

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

Автор: Alex Storm

Получить ссылку на материал

Категория: WinAPI | Добавил: Барон (20.12.2011)
Просмотров: 982 | Теги: VCL | Рейтинг: 0.0/0
[ Пожертвования для сайта ] [ Пожаловаться на материал ]

Если вам помог материал сайта кликните по оплаченной рекламе размещенной в центре

Поиск
Категории раздела
ActiveX [10]
CORBA и COM [16]
Kol и MCK [23]
WinAPI [28]
Компоненты [27]
Работа с Bluetooth [4]
Железо [8]
Текст [18]
Разное [98]
Королевство Delphi © 2010-2024
Яндекс цитирования