2012-08-02 21 views
21

Ho cercato un po 'su StackOverflow e Google ma non sono riuscito a ottenere l'idea. Voglio iniziare la mia applicazione con questo tipo di programmazione da parte dell'utente:Sostituzione di WinMain() con la funzione main() nei programmi Win32

int main() 
{ 
    Window App("Test", 640, 480); 

    while(App.IsOpen()) 
    { 
    // Do the stuff 
    } 
} 

Ma questo non è possibile perché dovrei passare il hInstance e hPrevInstance ed altri parametri a una funzione WinMain. In realtà c'è una classe Window che ho progettato per rendere la creazione della finestra un po 'più semplice. Ho visto questa implementazione su SFML ma non so come sia arrivata a questo.

Proprio ora sto usando il solito modo:

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR, int) 
{ 
    Window App(hInst, hPrevInst, "Test", 640, 480); 

    while(App.IsOpen()) 
    { 
    // Do the stuff 
    } 
} 

Grazie.

risposta

28

È possibile utilizzare standard di main in un app "finestre" (vale a dire, un sottosistema GUI applicazione Windows), anche con gli strumenti Microsoft, se si aggiunge quanto segue per le opzioni di linker Microsoft:

/subsystem:windows /ENTRY:mainCRTStartup 

Nota che questo non è necessario per la toolchain GNU.

Ancora per gli strumenti Microsoft in alternativa è possibile aggiungere questo al vostro file principale:

#ifdef _MSC_VER 
# pragma comment(linker, "/subsystem:windows /ENTRY:mainCRTStartup") 
#endif 

@James McNellis ti dice come ottenere il hInstance.

+0

Grazie. Con la tua risposta e altri finalmente l'ho fatto! :) – MahanGM

+2

Modifica: invece di lamentarmi della risposta fuorviante, l'ho appena corretto. –

+1

Originariamente ho eseguito il rollback di questa modifica perché penso che la risposta fosse più chiara per la grande maggioranza delle persone che cercano di farlo funzionare su una piattaforma Windows, non c'è bisogno di parlare di gnu perché 1) la maggior parte delle persone non usa su Windows, e 2) non avrebbero comunque avuto questo problema .... Ma non voglio entrare in un argomento quindi ho comunque ripristinato la tua modifica :) – jcoder

15

GetModuleHandle(NULL) ti darà hInstance. hPrevInstance è sempre NULL.

+0

Gli altri parametri possono essere ottenuti senza 'WinMain' troppo: http://stackoverflow.com/a/ 25250854/103167 –

12

Innanzitutto, GetModuleHandle(0) fornisce l'handle del modulo dell'eseguibile, che è lo stesso dell'argomento hInstance di WinMain.

Con GNU toolchaing (compilatore g ++), il codice conforme allo standard è OK.

La toolchain di Microsoft, tuttavia, accetta solo il codice conforme allo standard per l'eseguibile di un sottosistema di console. Per creare un eseguibile del sottosistema della GUI con questa toolchain non conforme, utilizzando uno standard main, è necessario specificare un punto di ingresso della libreria runtime Microsoft che chiami lo standard main, ovvero mainCRTStartup. Per una chiamata a linea di comando che significa & hellip;

cl myApp.cpp /link /entry:mainCRTStartup /subsystem:windows user32.lib 

In pratica, per lavorare nella riga di comando è possibile specificare semplicemente il punto di ingresso nella variabile LINK ambiente:

set LINK=/entry:mainCRTStartup 

& hellip;

cl myApp.cpp /link /subsystem:windows user32.lib 

Creazione di una configurazione standard conforme simile per Visual Studio è forse non è auspicabile, dal momento che alcuni tipi di progetti di Visual Studio (principalmente MFC) richiede l'utilizzo di Microsoft non standard WinMain o wWinMain.

4

hInstance è un'eccezione alla regola del pollice "non utilizzare mai le variabili globali". Normalmente nessuna variabile in realtà ha logicamente un ambito che è esteso al modulo.hInstance, tuttavia, ha per definizione esattamente l'ambito del modulo, quindi in realtà la soluzione più logica è quella di creare una variabile globale e inizializzarla in WinMain.

Come altri hanno suggerito, è anche possibile utilizzare GetModuleHandle(NULL).

+0

Questo in realtà non è vero. Si consideri, ad esempio, la compilazione di una lib statica. Esiste solo un file 'HINSTANCE' per PE. – Puppy

+0

Sì, ma per il codice che usa la variabile globale, non c'è differenza. L'ambito massimo che una variabile può avere è a livello di modulo. Meno portata di quella non può far male. – tenfour

+0

Ma non c'è ancora bisogno di avere più portata. – Puppy

-1

Semplice:

#define MainCode int WINAPI WinMain (HINSTANCE hThisInstance,HINSTANCE hPrevInstance,LPSTR lpszArgument,int nCmdShow) 


MainCode 
{ 
.... your code here .... 
} 

È possibile nascondere la prima linea mettendolo in un altro file

Problemi correlati