La fonction CreateWindowEx échoue mais GetLastError () renvoie ERROR_SUCCESS
Je suis en train de créer une fenêtre simple avec C/C++ à l'aide de natif de Windows file d'attente de messages (sans .NET). J'ai suivi la MSDN tutoriel et a écrit quelques-uns de base du code qui crée une fenêtre vide:
void main()
{
HINSTANCE hinst;
HWND hwndMain;
WNDCLASSEX wnd;
MSG msg;
hinst = GetModuleHandle( NULL );
memset( &wnd, 0, sizeof( wnd ) );
wnd.cbSize = sizeof( wnd );
wnd.lpszClassName = "MainWClass";
wnd.lpfnWndProc = MainWProc;
wnd.hInstance = hinst;
int result = RegisterClassEx( &wnd );
if( !result )
{
printf("RegisterClassEx error: %d\r\n", GetLastError() );
}
hwndMain = CreateWindowEx
(
0, //extended styles
wnd.lpszClassName, //class name
"Main Window", //window name
WS_OVERLAPPEDWINDOW | WS_HSCROLL | WS_VSCROLL | WS_MINIMIZEBOX, //style tags
CW_USEDEFAULT, //horizontal position
CW_USEDEFAULT, //vertical position
CW_USEDEFAULT, //width
CW_USEDEFAULT, //height
(HWND) NULL, //parent window
(HMENU) NULL, //class menu
(HINSTANCE) wnd.hInstance, //some HINSTANCE pointer
NULL //Create Window Data?
);
if( !hwndMain )
{
printf("Oh shi- %d\n", GetLastError() );
}
ShowWindow( hwndMain, SW_SHOWDEFAULT );
UpdateWindow( hwndMain );
}
Quand je exécuter/déboguer le programme, CreateWindowEx renvoie la valeur 0, ce qui signifie qu'il a échoué. Cela déclenche le message d'erreur "Oh shi- [code d'erreur]". Le plus déroutant, c'est que le message d'erreur d'impressions à la console:
Oh shi - 0
Le code d'erreur renvoyé par GetLastError() est 0, ce qui est ERROR_SUCCESS!
Je suis à une perte totale; ce qui se passe? Je suis tellement confuse...
P. S.
Je suis à l'aide de Visual C++ Express 2010 sur Windows 7 32 bits. J'ai écrit une Procédure de Windows par ailleurs, mais il renvoie 0 pour tous les cas. Cependant, si quelqu'un veut le voir, je serai heureux de le montrer.
J'ai changé le Projet de jeu de caractères par Défaut de mon projet Visual C++ pour "Non Défini". Je ne devrais pas besoin de préfixe L de mes choses.
Edit: ajout de wnd.hInstance = hinst;
Edit: suppression de l'inutile (WNDPROC) en fonte d'
Edit: ajout de la vérification des erreurs pour RegisterClassEx
Il s'avère que le problème était avec Visual C++ Express (ou du moins, pas avec le code lui-même). J'ai copié le code pour un autre projet et ça a fonctionné.
source d'informationauteur Joshua
Vous devez vous connecter pour publier un commentaire.
Nous ne pouvons pas voir la vraie raison pour laquelle vous devez utiliser la fonte, mais il est très louche. Windows renvoie 0 de GetLastError() si elle ne voit rien de mal. Ce qui peut se produire si la procédure de fenêtre est brisée. Comme celui-ci:
Windows envoie le message WM_NCCREATE pour demander la fenêtre pour être créé. Si ce message n'est pas de traiter alors il n'y aura pas de fenêtre. Et pas d'erreur. Correctif:
Ajuster si nécessaire pour personnaliser la fenêtre. Assurez-vous juste que DefWindowProc() est appelée pour chaque message que vous ne voulez pas gérer vous-même. Et garder Petzold à portée de main pour éviter les erreurs simples. Et perdre de la fonte.
Toutes les versions modernes de Windows utilisent Unicode en interne, et par défaut, les projets Visual Studio #define
_UNICODE
/UNICODE
ce qui provoque votre demande de lien pour les versions Unicode de la Windows les en-têtes.Lorsque vous compilez une application Unicode, cependant, le personnage (et donc de la "chaîne") les types sont différents. Au lieu de
char
ils sont maintenantwchar_t
. Cela signifie que vous avez à déclarer explicitement votre littéraux de chaîne de longues chaînes en les préfixant avec unL
.Sinon, Windows les en-têtes de cacher tout cela derrière les macros, mais il n'est plus nécessaire parce que Windows a été Unicode pour une longue période et que très peu de chances de changer.
Au-delà, il vous manque plusieurs choses dans votre initialisation de la
WNDCLASSEX
de la structure, comme lehInstance
membre. Toutes ces choses doivent être réglées à la perfection, ou les choses vont échouer. Ainsi, laRegisterClass(Ex)
etCreateWindow(Ex)
fonctions doit être passé le exactement la même chaîne valeurs correspondant au nom de la classe de fenêtre, sinon ils vont suppose que vous parlez de deux choses différentes. Les fautes de frappe ne sont pas pardonnés!Je recommande fortement que vous utilisez Visual Studio assistants pour créer un vide (mais de travail!) modèle de projet.
Le bon code réutilisable va quelque chose comme ceci:
Dans mon cas, j'ai eu à gérer WNC_NCCREATE manuellement. DefWindowProc retourné à zéro pour WNC_NCCREATE, je l'ai résolu avec:
J'ai eu le même problème.
Dans mon cas, c'est juste que j'ai utilisé visual sutdio sans droits d'administrateur.
Et j'ai découvert que dans ce cas je ne peux pas déboguer mon application.
En mode de débogage sans droit d'administration, CreateWindowEx retourner la valeur null avec le code d'erreur résultat de 0, comme vous.
Mais si vous allez construire votre répertoire, vous pouvez utiliser votre application (pas en mode debug).
Donc, si ce le cas pour vous aussi, il suffit de commencer visula studio avec droit d'administration et de son fait.
Je pense qu'il y a presque un moyen d'utiliser visual studio en mode debug avec droit admin sans démarrez visual studio avec mot de passe admin à chaque fois. je ne sais pas comment le faire, mais je pense que c'est peut-être possible.