Мегабайты отдыхают

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
Теги:
ресурсы компьютера
Добавлено: 04 Августа 2018 07:46:35 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...