2012-08-02 12 views
21

He buscado un poco en StackOverflow y Google, pero no pude entender la idea. Quiero empezar mi aplicación con este tipo de programación del usuario:Reemplazando WinMain() con la función main() en programas Win32

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

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

Pero esto no es posible porque debería pasar el hInstance y hPrevInstance y otros parámetros a una función WinMain. En realidad, hay una clase de ventana que diseñé para hacer que la creación de Windows sea un poco más fácil. Vi esta implementación en SFML, pero no sé cómo llegó a esto.

En este momento estoy usando la forma habitual:

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

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

Gracias.

Respuesta

28

Puede utilizar norma main en una aplicación de "ventanas" (es decir, una aplicación de subsistema de interfaz gráfica de usuario de Windows), incluso con las herramientas de Microsoft, si se añade lo siguiente a las opciones del vinculador de Microsoft:

/subsystem:windows /ENTRY:mainCRTStartup 

Nota que esto no es necesario para la cadena de herramientas GNU.

Aún para las herramientas de Microsoft, alternativamente, se pueden agregar esto a su archivo principal:

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

@ James McNellis te dice cómo obtener el hInstance.

+0

Gracias. ¡Con tu respuesta y otras finalmente lo hice! :) – MahanGM

+2

Editar: en lugar de lloriquear sobre la respuesta engañosa que acaba de corregirlo. –

+1

Originalmente reimplanté esta edición porque creo que la respuesta fue más clara para la gran mayoría de las personas que intentan hacer que esto funcione en una plataforma de Windows, no hay necesidad de hablar sobre GNU porque 1) la mayoría de la gente no usa en Windows, y 2) no habrían tenido este problema de todos modos ... Pero no quiero entrar en una discusión, así que he devuelto la edición de todos modos :) – jcoder

15

GetModuleHandle(NULL) le dará hInstance. hPrevInstance es siempre NULL.

+0

Los demás parámetros se pueden conseguir sin demasiado 'WinMain': http://stackoverflow.com/a/ 25250854/103167 –

12

Primero, GetModuleHandle(0) proporciona el identificador del módulo ejecutable, que es el mismo que el argumento hInstance de WinMain.

Con la herramienta GNU toolchaing (compilador g ++), el código de conformidad estándar está bien.

La cadena de herramientas de Microsoft, sin embargo, solo acepta el código de conformidad estándar de forma predeterminada para un subsistema de consola ejecutable. Para crear un subsistema de GUI ejecutable con esta cadena de herramientas no conforme, utilizando un estándar main, debe especificar un punto de entrada de biblioteca de tiempo de ejecución de Microsoft que llame al estándar main, a saber, mainCRTStartup. Para una invocación de línea de comando que significa & hellip;

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

En la práctica, para trabajar en la línea de comandos, puede simplemente especificar el punto de entrada en la variable de entorno LINK:

set LINK=/entry:mainCRTStartup 

y hellip;

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

Creación de una configuración que sigan los estándares similares para Visual Studio es quizás no es deseable, ya que algunos tipos de proyecto de Visual Studio (principalmente MFC) requiere el uso de Microsoft de no estándar o WinMainwWinMain.

4

hInstance es una excepción a la regla general "nunca usar variables globales". Normalmente, ninguna variable tiene lógicamente un ámbito que abarque todo el módulo.hInstance, sin embargo, tiene por definición el alcance de todo el módulo, por lo que en realidad la solución más lógica es hacer una variable global para él e inicializarlo en WinMain.

Como han sugerido otros, también puede usar GetModuleHandle(NULL).

+0

Eso no es cierto. Considere, por ejemplo, compilar una lib estática. Solo hay un 'HINSTANCE' por archivo PE. – Puppy

+0

Sí, pero para el código que usa la variable global, no hay diferencia. El alcance máximo que puede tener una variable es todo el módulo. Menos alcance que eso no puede doler. – tenfour

+0

Pero aún no es necesario que tenga más alcance. – Puppy

-1

simple:

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


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

Puede ocultar la primera línea poniéndolo en otro archivo

Cuestiones relacionadas