怎樣使用 Visual C++ 編譯出只有 1536 位元組的視窗程式

看雪資料發表於2015-11-15

//題目:怎樣使用 Visual C++ 編譯出只有 1536 位元組的視窗程式
//這些技巧都是dREAMtHEATER老大哥告我的……
//編譯出來後,檔案大小為: 1536 位元組


////////////////////////////////////////////////////////////////////////////////////////////////////
//預處理

#include <Windows.h>

//使用了下面的預處理,編譯連線時必須是 Release 方式,否則不能通過


//自定義程式入口,如果要優化,推薦使用這個
//如果使用 VS.NET,也可以這樣設定:在“解決方案管理器”裡選定專案,右擊,選擇“屬性”->“連結器”->“高階”->“入口點”
//VC 6裡面也有類似的設定,但具體不記得了
//專案屬性的其它設定可以仔細看看,其它優化也都在這裡可以設定

#pragma comment(linker, "/ENTRY:EntryPoint")


//下面是調整段對齊,預設是 4K,在 Win98 下能更快地裝入 PE 檔案,但會增加 PE 檔案的大小
//下面這一行在這裡好像會說是“無效的指令”什麼的,故在這裡也註釋掉了,也許是段太小的原因吧。
//直接在工程選項裡面設定:專案“屬性”->“連結器”->“優化”->“Windows98 優化”->“否 (/OPT:NOWIN98)”
//#pragma comment(linker, "/OPT:NOWIN98")


//下面的優化是段合併,不推薦使用,在很多程式裡也許也許不能使用

#pragma comment(linker, "/SECTION:MiniPE,")             //建立自定義的 MiniPE Section
#pragma comment(linker, "/MERGE:.data=MiniPE")  //合併.data Section 到 MiniPE Section
#pragma comment(linker, "/MERGE:.text=MiniPE")  //合併.text Section 到 MiniPE Section
#pragma comment(linker, "/MERGE:.rdata=MiniPE") //合併.rdata Section 到 MiniPE Section
////////////////////////////////////////////////////////////////////////////////////////////////////



////////////////////////////////////////////////////////////////////////////////////////////////////
//全域性變數

HWND                                    g_hWnd;         //主視窗控制程式碼,一般程式中經常用到此變數,故使用全域性變數
HINSTANCE                               g_hInst;        //應用程式程式控制程式碼,一般程式中經常用到此變數,故使用全域性變數

const char                              c_szAppName[] = "MiniPE";
////////////////////////////////////////////////////////////////////////////////////////////////////



////////////////////////////////////////////////////////////////////////////////////////////////////
//函式宣告

LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow);
////////////////////////////////////////////////////////////////////////////////////////////////////




////////////////////////////////////////////////////////////////////////////////////////////////////
//入口函式
//使用我們自己的入口函式,而不用聯結器預設提供的一大堆程式初始化操作的程式碼
//為了在一個普通的 Win32SDK 程式裡能使用這種方法,下面的函式將呼叫 WinMain() 函式,並給出相應的引數

void EntryPoint()
{
       ExitProcess(WinMain(GetModuleHandle(NULL), NULL, GetCommandLine(), SW_SHOWNORMAL));
}
////////////////////////////////////////////////////////////////////////////////////////////////////



////////////////////////////////////////////////////////////////////////////////////////////////////
//主函式

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow)
{
       MSG                                             sMsg;
       WNDCLASSEX                              sWndClassEx;


       g_hInst = hInstance;

       sWndClassEx.cbSize = sizeof(WNDCLASSEX);
       sWndClassEx.style = CS_VREDRAW | CS_HREDRAW;
       sWndClassEx.lpfnWndProc = (WNDPROC) WindowProc;
       sWndClassEx.cbClsExtra = 0;
       sWndClassEx.cbWndExtra = 0;
       sWndClassEx.hInstance = g_hInst;
       sWndClassEx.hIcon = LoadIcon(NULL, IDI_APPLICATION);
       sWndClassEx.hCursor = LoadCursor(NULL, IDC_ARROW);
       sWndClassEx.hbrBackground = (HBRUSH) (COLOR_WINDOW);
       sWndClassEx.lpszMenuName = NULL;
       sWndClassEx.lpszClassName = c_szAppName;
       sWndClassEx.hIconSm = NULL;
       RegisterClassEx(&sWndClassEx);

       g_hWnd = CreateWindowEx(0, c_szAppName, c_szAppName, WS_OVERLAPPEDWINDOW,
               CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
               NULL, NULL, g_hInst, NULL);
       ShowWindow(g_hWnd, iCmdShow);
       UpdateWindow(g_hWnd);

       while (GetMessage(&sMsg, NULL, 0, 0))
       {
               TranslateMessage(&sMsg);
               DispatchMessage(&sMsg);
       }
       return((int) sMsg.wParam);
}
////////////////////////////////////////////////////////////////////////////////////////////////////



////////////////////////////////////////////////////////////////////////////////////////////////////
//主視窗回撥函式

LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
       switch (uMsg)
       {
       case WM_DESTROY:
               PostQuitMessage(0);
               break;

       default:
               return(DefWindowProc(hWnd, uMsg, wParam, lParam));
       }
       return(0);
}
////////////////////////////////////////////////////////////////////////////////////////////////////

相關文章