IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

MFC Discussion :

[Débutant] Affichage d'un Bitmap d'après resource


Sujet :

MFC

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 42
    Points : 24
    Points
    24
    Par défaut [Débutant] Affichage d'un Bitmap d'après resource
    Bonjours,

    J'essaie d'afficher sur le fond de la fenêtre de mon application, une image au format BMP.

    Je l'ai déclaré dans les ressources, j'essaie en suite de l'utiliser, et j'ai une Violation d'acces mémoire. J'ai récupéré un bout de code que j'ai essayé de transormer.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    case WM_PAINT:
    				HDC hdc;
    				HDC hdcMemory;
    				PAINTSTRUCT ps;
     
    				hdc = BeginPaint(hWnd, &ps);
    				BITMAP bm;
    				hbitmap = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE("BGSTEP1"), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); 
    				hdcMemory = CreateCompatibleDC(NULL); 
    				SelectObject(hdcMemory, hbitmap);
    				GetObject(hbitmap, sizeof(bm), &bm);
    				BitBlt(hdc, 0, 0, bm.bmWidth, bm.bmHeight, hdcMemory, 0, 0, SRCCOPY);
     
    				DeleteDC(hdcMemory);
    				EndPaint(hWnd, &ps);
    		break;
    Et dans le resource.rc :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    BGSTEP1 BITMAP "BgStep1.bmp"
    Merci de votre aide

  2. #2
    Rédacteur
    Avatar de nico-pyright(c)
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    6 414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 6 414
    Points : 16 075
    Points
    16 075
    Par défaut
    où se situe la violation ?

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 42
    Points : 24
    Points
    24
    Par défaut
    Dans la fenêtre de sortie de Visual Studio :

    First-chance exception at 0x7c80b8a2 in Installer.exe: 0xC0000005: Access violation reading location 0x00009dbc.

  4. #4
    Rédacteur
    Avatar de nico-pyright(c)
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    6 414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 6 414
    Points : 16 075
    Points
    16 075
    Par défaut
    hum ...

    Execute ton programme pas à pas en debug, et repère la ligne qui te provoque cette erreur, qui doit etre dûe à une mauvaise utilisation d'un pointeur

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 42
    Points : 24
    Points
    24
    Par défaut
    Mais le code en lui même semble valide? Etant débutant je fais surtout de la bidouille pour que ça fonctionne.

    Je n'ai pas réussi à obtenir d'informations depuis le debuger, je ne sais en plus pas encore très bien m'en servir.

    Le problème semble bien venir de la partie que j'ai donnée, dès que je la commente je n'ai plus de problème.

    Mon but est d'afficher un bitmap contenu dans les ressources en fond de la fenêtre.

    Merci pour votre aide

    [Edit]

    La ligne qui pose problème semble être :

    hbitmap = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE("BGSTEP1"), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);

  6. #6
    Rédacteur
    Avatar de nico-pyright(c)
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    6 414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 6 414
    Points : 16 075
    Points
    16 075
    Par défaut
    il ne faut pas combiner le flag LR_LOADFROMFILE et un chargement depuis une ressource.
    C'est soit LR_LOADFROMFILE et une adresse de fichier sur le disque dur
    soit c'est un chargement depuis une ressource, et il ne faut pas utiliser ce flag.
    Voir détails dans msdn http://msdn.microsoft.com/library/de.../loadimage.asp

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 42
    Points : 24
    Points
    24
    Par défaut
    Merci, je n'ai plus l'erreur de violation de mémoire.

    Cependant, l'image ne s'affiche toujours pas.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    		case WM_PAINT:
    			HDC hdc;
    			HDC hdcMemory;
    			PAINTSTRUCT ps;
    			HBITMAP hbitmap;
    			HINSTANCE hInstance;
    			BITMAP bm;
     
    			hdc = BeginPaint(hWnd, &ps);
    			hbitmap = (HBITMAP)LoadImage(NULL, MAKEINTRESOURCE("BGSTEP1"), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
    			hdcMemory = CreateCompatibleDC(NULL);
    			SelectObject(hdcMemory, hbitmap);
    			GetObject(hbitmap, sizeof(bm), &bm);
    			BitBlt(hdc, 0, 0, bm.bmWidth, bm.bmHeight, hdcMemory, 0, 0, SRCCOPY);
     
    			DeleteDC(hdcMemory);
    			EndPaint(hWnd, &ps);
    		return 0;

  8. #8
    Rédacteur
    Avatar de nico-pyright(c)
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    6 414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 6 414
    Points : 16 075
    Points
    16 075
    Par défaut
    je t'encourage vivement à tester les retours des API (loadImage, Bitblt, etc ..)

  9. #9
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    PS: MAKEINTRESOURCE est inutile quand tu passes une chaîne.
    Comme son nom l'indique mal, tu en as besoin quand tu passes un entier.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  10. #10
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 42
    Points : 24
    Points
    24
    Par défaut
    Voici l'état actuel de mon code. Malheureusement j'ai passé au peigne tous les tutoriaux du net pour trouver des informations mais mon image ne s'affiche toujours pas.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    		case WM_PAINT:
    			HBITMAP hBmp;
    			HDC hDC;
    			hBmp = (HBITMAP)LoadImage(NULL, "BGSTEP1", IMAGE_BITMAP, 0, 0, NULL);
    			hDC = GetDC(hWnd);
    			DrawState(hDC, NULL, NULL, (LPARAM)hBmp, NULL, 0, 0, 0, 0, DST_BITMAP);
    			DeleteObject(hBmp);
    			ReleaseDC(hWnd, hDC);
    		return 0;
    Je desespère un peu. Comment puis-je faire?
    Merci

  11. #11
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Tu ne passes pas le HINSTANCE de ton exécutable. Résultat, LoadImage() cherche une image système...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  12. #12
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 42
    Points : 24
    Points
    24
    Par défaut
    J'ai fais comme ça, mais ça ne fonctionne pas.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    		HINSTANCE hInstance;
     
    		case WM_PAINT:
    			HBITMAP hBmp;
    			HDC hDC;
    			hBmp = (HBITMAP)LoadImage(hInstance, "BGSTEP1", IMAGE_BITMAP, 0, 0, NULL);
    			hDC = GetDC(hWnd);
    			DrawState(hDC, NULL, NULL, (LPARAM)hBmp, NULL, 0, 0, 0, 0, DST_BITMAP);
    			DeleteObject(hBmp);
    			ReleaseDC(hWnd, hDC);
    		return 0;

  13. #13
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Il est bien initialisé, au moins ?
    (avec le paramètre hInstance de WinMain())

    Et aussi, utilise GetLastError() et FormatMessage() pour savoir exactement quelle est l'erreur renvoyée.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  14. #14
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 42
    Points : 24
    Points
    24
    Par défaut
    Voici la totalité de ma page :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    #include <iostream>
    #include <windows.h>
    #include "resource.h"
    #include "main.h"
     
     
    ///////////////////////////////////////////////////////////
     
    int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
    {
    	WNDCLASSEX main;
    	main.cbSize = sizeof(WNDCLASSEX);
    	main.style = CS_HREDRAW|CS_VREDRAW;
    	main.lpfnWndProc = MainProc;
    	main.cbClsExtra = 0;
    	main.cbWndExtra = 0;
    	main.hInstance = hInstance;
    	main.hIcon = LoadIcon(hInstance, "APPICON");
    	main.hIconSm = LoadIcon(hInstance, "WINICON");
    	main.hCursor = LoadCursor(NULL, IDC_ARROW);
    	main.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);
    	main.lpszMenuName = NULL;
    	main.lpszClassName = "std";
    	RegisterClassEx(&main);
    	HWND hWnd;
    	hWnd = CreateWindowEx(WS_EX_CLIENTEDGE, "std", "Installation", WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT, 609, 429, NULL, NULL, hInstance, NULL);
    	ShowWindow(hWnd, SW_SHOW);
    	SetTimer(hWnd, NULL, 1000, NULL);
    	MSG messages;
     
    	while(GetMessage(&messages, NULL, 0, 0) == TRUE)
    	{
    		TranslateMessage(&messages);
    		DispatchMessage(&messages);
    	}
     
    	return 0;
    }
     
    ///////////////////////////////////////////////////////////
     
    LRESULT CALLBACK MainProc(HWND hWnd, UINT messages, WPARAM wParam, LPARAM lParam)
    {
    	switch (messages)
    	{
    		HINSTANCE hInstance;
     
    		case WM_PAINT:
    			HBITMAP hBmp;
    			HDC hDC;
    			hBmp = (HBITMAP)LoadImage(hInstance, "BGSTEP1", IMAGE_BITMAP, 0, 0, NULL);
    			hDC = GetDC(hWnd);
    			DrawState(hDC, NULL, NULL, (LPARAM)hBmp, NULL, 0, 0, 0, 0, DST_BITMAP);
    			DeleteObject(hBmp);
    			ReleaseDC(hWnd, hDC);
    		return 0;
     
    		case WM_CLOSE:
                if(MessageBox(hWnd, "Êtes vous sûr de vouloir annuler l'installation ?", "Installation", MB_YESNO|MB_ICONQUESTION) == IDYES)
    				DestroyWindow(hWnd);
    		break;
     
    		case WM_DESTROY:
    			PostQuitMessage(0);
    		break;
     
    		default:
    		return DefWindowProc(hWnd, messages, wParam, lParam);
    	}
    }

  15. #15
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    En clair, tu passes à LoadImage() un HINSTANCE non-initialisé...

    Bon, tu as deux solutions:
    • Soit mémoiriser le HINSTANCE reçu en paramètre de WinMain() dans une variable globale (seule solution qui marcherait dans une DLL),
    • soit tu initialises ton HINSTANCE avec la valeur retournée par GetModuleHandle(NULL) (ceci, ça ne marche que dans l'EXE).
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  16. #16
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 42
    Points : 24
    Points
    24
    Par défaut
    Merci,

    j'ai essayé ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    			HINSTANCE hInstance;
    			hInstance = GetModuleHandle(NULL);
    			HBITMAP hBmp;
    			HDC hDC;
    			hBmp = (HBITMAP)LoadImage(hInstance, "BGSTEP1", IMAGE_BITMAP, 0, 0, NULL);
    			hDC = GetDC(hWnd);
    			DrawState(hDC, NULL, NULL, (LPARAM)hBmp, NULL, 0, 0, 0, 0, DST_BITMAP);
    			DeleteObject(hBmp);
    			ReleaseDC(hWnd, hDC);
    Et l'image s'affiche. Seulement, les deplacements de la fenêtre crés des lenteurs de rafraichissement (des genres de petites rainures) et je ne peux plus fermer l'application avec le message de confirmation.

  17. #17
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Je ne connais pas DrawState.
    Mais, si tu veux un bon conseil (avec l'autre méthode), charge ton image et crée ton Compatible DC à la création de la fenêtre, pour le détruire dans le traitement de WM_DESTROY...

    D'une manière générale, je te conseille de t'arranger pour exporter le plus de traitements possibles en dehors du traitement de WM_PAINT...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  18. #18
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 42
    Points : 24
    Points
    24
    Par défaut
    Je suis perdu. Je ne comprends pas assé pour réaliser le code qu je souhaite.

    Ou puis je trouver des tuto sur ce que je dois faire exactement?

  19. #19
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 42
    Points : 24
    Points
    24
    Par défaut
    J'ai placé mon bout de code d'affichage de la page dans la fonction de création de la fenêtre. Biensûr maintenant la page n'est plus redessinez lorsqu'elle passe derrière une autre.

    J'ai aussi l'impression que si je place le code dans le switch, elle est executé sans arret car mon processeur monte à 100% de charge.

    Comment puis je faire pour rafraichir la page seulement en cas de besoin?

    Merci

  20. #20
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Relis ce que j'ai écrit: tu prépares l'affichage dans le WM_CREATE, tu mémorises l'image, etc.

    et tu l'affiches dans le WM_PAINT.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

Discussions similaires

  1. Réponses: 4
    Dernier message: 28/02/2006, 14h25
  2. [Débutant] Affichage d'une grille
    Par Mathieu.J dans le forum OpenGL
    Réponses: 25
    Dernier message: 13/06/2004, 19h38
  3. Affichage d'une bitmap et de l'heure
    Par nanarr dans le forum Assembleur
    Réponses: 14
    Dernier message: 16/04/2004, 22h39
  4. [QuickReport][Débutant] Affichage d'un graphique
    Par poufouille dans le forum Bases de données
    Réponses: 3
    Dernier message: 23/03/2004, 09h03
  5. [Débutant] Affichage impossible en local
    Par Alberto dans le forum ASP
    Réponses: 2
    Dernier message: 29/11/2003, 16h45

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo