2012-01-09 104 views
2

我已經設置了進入WinMain的入口點,但是當我運行該應用程序時它啓動並且不顯示,然後我必須用任務管理器關閉它。下面是高達的WinMain(代碼):如何在Visual Studio中正確設置exe的入口點?

#include <Windows.h> 

// forward declarations 
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); 

// The entry point into a windows program 
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int windowStyle) 
{ 
.... 

我不是在C++中有經驗,我不知道這是什麼做的,只是讓我的exe文件更小,這就是我想要的目的。

編輯:我想要做的是創建一個非常小的窗口EXE來了解如何演示編碼器的工作。所以我想創建一個小型的c + +窗口應用程序,提供一個窗口句柄,我可以附加SlimDX(如果我可以靜態鏈接最終的c + + dll到C#應用程序,但我還沒有)我有我的BasicWindow .exe下降到6,656字節。所以我正在試驗我能找到的任何東西,以便將這個尺寸縮小到< 3k。

[2012.Jan.10]好吧,我已經通過在VS2010下重建minicrt(可從http://www.benshoof.org/blog/small-programs/獲得)並將其作爲附加依賴項添加進來,取得了一些成功。我無法按照建議忽略所有默認庫,但我現在有一個窗口應用程序,其exe大小爲4,096字節。我會說這是一個重大的成功。我現在處於驚人的距離內。從這裏開始每減少一次,SlimDX的空間就會更大。考慮到我曾經寫過的唯一C++應用程序是控制檯應用程序和基本窗口,我非常高興:)我很幸運,我知道!

+0

你在哪裏準確設置入口點? – Default 2012-01-09 16:08:00

+0

屬性>配置屬性>鏈接器>高級>入口點= WinMain – 2012-01-09 16:16:41

回答

5

一個典型的應用程序不應該混淆連接器的Entry point設置。入口點應在標準運行時庫中包含的函數上設置(針對windows子系統的unicode應用程序爲wWinMainCRTStartup)。這個函數的作用就像正確地初始化CRT和創建全局對象。通過將入口點重新路由到您的WinMain,您將得到未定義的行爲,除非您確切知道您在做什麼以及以某種方式在您自己的WinMain中實施CRT初始化。在我看來,由此造成的尺寸減少將是可以忽略的,整個事件都不值得冒這個風險。

+0

你似乎對這些問題加提成這裏討論www.benshoof.org/blog/small-程序/很明顯,我需要更深入地理解這個主題,才能期待奇蹟出現改變。也許需要使用類似minicrt的東西來正確更改入口點。 – 2012-01-09 16:45:02

+0

我會說風險並不重要,因爲這是瞭解演示如何工作的一個簡短實驗過程。但是,之後,Ive試圖查看的一半以上演示程序根本無法在我的電腦上運行,所以這就是風險。 – 2012-01-09 16:51:46

+0

@GavinWilliams:我錯過了你在編輯時輸入我的答案。現在我看到你的方法的實驗性質。哦,好吧......我想你現在已經自己回答了你的問題,考慮你給出的鏈接:) – 2012-01-09 17:23:21

2

當您設置的入口點WinMain,Windows不會給你的程序的控制檯窗口,因爲WinMain是與不需要控制檯窗口的GUI程序。你的程序確實在運行,雖然沒有GUI,但你沒有看到任何事情發生。

+0

我不明白,因爲這是一個Win32應用程序,並且我創建/註冊了一個窗口。並稱爲ShowWindow()。所以我的程序不需要控制檯窗口,因爲它有一個Win32窗口。如果我沒有設置EntryPoint,窗口顯示正確。你是說所有的窗口都在控制檯窗口中運行嗎?並且被刪除的代碼是提供該控制檯窗口的代碼?也許你是說使用窗口的任何應用程序都不能更改入口點? – 2012-01-09 16:05:47

+0

@GavinWilliams設置在調試器斷點的代碼在'WinMain'的第一行,並在調試器中運行它,看看斷點命中 – 2012-01-09 16:07:32

+0

不,這不是打擊,VS顯示,雖然任務管理人員說,應用程序已終止它仍在運行。 – 2012-01-09 16:10:41

0

僅供參考,以下是完整的程序:

#include <Windows.h> 

// forward declarations 
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); // WindowProcedure function 

// The entry point into a windows program 
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int windowStyle) 
{ 
// create and register a local window class > exit on failure 
WNDCLASSEX wcx; 
HINSTANCE zhInstance = GetModuleHandle(NULL); 
wcx.cbSize = sizeof(WNDCLASSEX);    // size of structure 
wcx.style = CS_HREDRAW | CS_VREDRAW;   // redraw if size changes 
wcx.lpfnWndProc = WndProc;      // window procedure 
wcx.cbClsExtra = 0;        // no extra class memory 
wcx.cbWndExtra = 0;        // no extra windows memory 
wcx.hInstance = zhInstance;      // handle to instance (owner) 
wcx.hIcon = LoadIcon(NULL, IDI_APPLICATION); // predefined icon 
wcx.hCursor = LoadCursor (NULL, IDC_ARROW);  // predefined arrow 
wcx.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);//(HBRUSH) (COLOR_WINDOW + 1);// white background brush 
wcx.lpszMenuName = NULL;      // name of menu resource 
wcx.lpszClassName = TEXT("BasicWindow");  // name of window class 
wcx.hIconSm = (HICON)LoadImage(zhInstance,    // small class icon 
    MAKEINTRESOURCE(5), 
    IMAGE_ICON, 
    GetSystemMetrics(SM_CXSMICON), 
    GetSystemMetrics(SM_CYSMICON), 
    LR_DEFAULTCOLOR); 

if (!RegisterClassEx(&wcx)) 
{ 
    MessageBoxA(0, "Error registering window class!","Error",MB_ICONSTOP | MB_OK); 
    DWORD result = GetLastError(); 
    return 0; 
} 

// create window > exit on failure 
HWND hwnd; // the window handle 
hwnd = CreateWindowEx(
    WS_EX_STATICEDGE, 
    wcx.lpszClassName, 
    TEXT("Basic Window"), 
    WS_OVERLAPPEDWINDOW, 
    CW_USEDEFAULT, 
    CW_USEDEFAULT, 
    320, 
    240, 
    NULL, 
    NULL, 
    zhInstance, 
    NULL); 

if (hwnd == NULL) 
{ 
    MessageBoxA(0,"Error creating window!","Error",MB_ICONSTOP | MB_OK); 
    return 0; 
} 

// show window 
ShowWindow(hwnd, SW_MAXIMIZE); 
// send a WM_PAINT message to the window 
UpdateWindow(hwnd); 

// enter message loop, break out of loop if there is an error (result = -1) 
MSG msg; // for storing the windows messages 
int status; // for storing the status of the windows message service where -1 = error, 0 = WM_QUIT, n = any other message) 
while ((status = GetMessage(&msg,(HWND) NULL,0,0)) != 0 && status != -1) 
{ 
    TranslateMessage(&msg); 
    DispatchMessage(&msg); 
} 

return msg.wParam; 
    UNREFERENCED_PARAMETER(lpCmdLine); 
} 

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 
{ 
switch(message) 
{ 
case WM_CLOSE: 
    DestroyWindow(hWnd); 
    break; 
case WM_DESTROY: 
    PostQuitMessage(0); 
default: 
    return DefWindowProc(hWnd,message,wParam,lParam); 
} 
return 0; 
} 
1

我有同樣的問題。我對answer marked here不滿意。因此,我開始深入挖掘,發現CreateWindowEx函數中缺少WS_VISIBLE。

WS_OVERLAPPEDWINDOWWS_VISIBLE使代碼完美工作。

以及有關文件的大小,我能夠使用的Visual Studio社區版2013在Windows 7旗艦版SP1 64位運行,以降低針對x64代碼的大小建立到 3,072字節1600字節。所有這些,沒有使用minicrt.lib,你在上面提到過。

下面是可執行屬性的屏幕截圖。

Properties Window showing file size

相關問題