Страница 1 из 4 Натыкаясь в Интернете на довольно интересные программы, я часто не решался их закачивать после того, как узнавал их размер. Какую ни возьми - все огромные. Да и ресурсов системных потребляют немало. В этой статье я расскажу о том, как сделать программу в среднем в 10 - 100 раз меньше размером, чем попадаются аналогичные.
Цель Написать очень быструю и маленькую программу, скрывающую по CTRL+F12 заданные окна. При нажатии комбинации CTRL+F10 она должна показать спрятанные окна. Входные данные: TXT Файл вида ------------ Internet Explorer The Bat! Visual C++ 911 ------------
Если будут найдены окна, содержащие в своем заголовке указанные строки, они будут спрятаны. В вышеуказанном примере будут спрятаны все окна IE, окно Microsoft Visual C++, окно почтовой программы "The Bat!" и все окна, в заголовках которых содержится комбинация символов "911". Итак, писать будем на чистом Win32 API. Создадим окно, привяжем к нему горячие клавиши. По требованию будем осуществлять перебор видимых окон в системе и в заголовке каждого будем искать заданные комбинации символов. Опции линкера Если ничего не предпринимать, то нам не удастся получить в итоге файл менее 32 КБ(примерно). Поэтому пишем: #pragma comment(linker,"/MERGE:.rdata=.text") #pragma comment(linker,"/FILEALIGN:512 /SECTION:.text,EWRX /IGNORE:4078") #pragma comment(linker,"/ENTRY:New_WinMain") #pragma comment(linker,"/NODEFAULTLIB")
На что теперь стоит обратить особое внимание? Обычно точка входа в программу выглядит так: int WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrevInst,LPSTR szCmdLine,int nCmdShow)
(кстати, для Win32 приложений второй параметр всегда NULL) Но(!)... Так как мы отключили "Runtime library", нам теперь передается в этих параметрах разный мусор. Поэтому называем точку входа не WinMain а New_WinMain, которую объявим, как void New_WinMain(void), чтобы не забыть о том, что нам ничего не передается. А параметр HINSTANCE получаем функцией GetModuleHandle(NULL). Ах да, и выходить из программы будем функцией ExitProcess. Теперь если собрать нашу пустую программку, которая ничего делать не будет, размер ее будет 1 Кб. Но нам нужно еще дописать 3 Кб кода. Продолжим. Чтобы все дальнейшее было понятно даже новичку в программировании под Windows, я прокомментирую все. Объявим кое-какие константы Это понадобится для регистрации "горячих" клавиш функцией RegisterHotKey. #define HOTKEYHIDE 1 #define HOTKEYSHOW 2
Размер буффера, куда будет считываться заголовок окна функцией GetWindowText. #define SSZZ 256
Размер буфера, куда будет считываться файл со стоками фильтрации (используется в объявлении char FilterStrings[MAXFIL];) #define MAXFIL 1024
(Примечание: При желании можно сделать и выделение памяти динамически - найти файл, узнать его размер и выделить блок. Приблизительный пример: // ..................... WIN32_FIND_DATA FindData; HANDLE hFind=FindFirstFile(szFilterStringsFile,&FindData); if (hFind!=INVALID_HANDLE_VALUE) { i=(FindData.nFileSizeHigh * MAXDWORD) + FindData.nFileSizeLow; HGLOBAL hGA=GlobalAlloc(GMEM_ZEROINIT|GMEM_MOVEABLE,i+1); // (+ end-ZERO) if (hGA!=NULL) { LPVOID lpStrings=GlobalLock(hGA); DWORD dw; if (lpStrings!=NULL) ReadFile(hFile,lpStrings,i,&dw,NULL); } } FindClose(hFind); CloseHandle(hFile); // ............................... // Но так как вряд ли файл настроек у нас будет больше одного // килобайта, я оставил статичный массив. )
Массив хендлов окон (вряд ли будет у нас более 300 окон) HWND aHwnd[300];
Кол-во инициализированных элементов в этом массиве unsigned int cHwnd=0;
Дескрипторы окон - главное и два дочерних - кнопка "Hide" и кнопка "Edit filter strings" HWND hwndMain, hwndButtonHide, hwndButtonEditFilter;
Тут будет что-то типа "c:\programs\winhider\winhider.settings.txt" char szFilterStringsFile[MAX_PATH]="(с)2002 KMiNT21";
Соответственно, хендл файла с именем "что-то типа" HANDLE hFile;
А это место, куда будем считывать все из этого файла char FilterStrings[MAXFIL]; |