Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1678 connectés 

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

GDI

n°2031809
borisbaski
Citation personnelle
Posté le 24-10-2010 à 12:05:03  profilanswer
 

Bonjour,
 
Une bonne âme pourrait elle m'aider ? Je ne comprends pas pourquoi mon code ne marche pas alors que j'ai essayé de suivre les préconisations de la MSDN et de différents forums. Un truc m'échappe...
 
Pour l'instant, je veux juste écrire un code simple, pour le complexifier par la suite.
 
Je définis en global :

Code :
  1. #define tailleX 800
  2. #define tailleY 600
  3. DWORD tableau[tailleX * tailleY];


 
J'éxécute en premier dans la winmain :

Code :
  1. for (int i=0;i<tailleX*tailleY;i++) tableau[i]=0x00FF00FF;


 
Et enfin, j'intercepte le message WM_PAINT. Je transforme tableau en hBitmap, puis je le redimensionne pour la fenêtre

Code :
  1. PAINTSTRUCT ps;
  2. HDC hdc=BeginPaint(hWnd, &ps);
  3. RECT tailleFenetre;
  4. BITMAPINFO bi;
  5. bi.bmiHeader.biBitCount=32;
  6. bi.bmiHeader.biClrImportant=0;
  7. bi.bmiHeader.biClrUsed=0;
  8. bi.bmiHeader.biCompression=BI_RGB;
  9. bi.bmiHeader.biHeight=tailleY;
  10. bi.bmiHeader.biWidth=tailleX;
  11. bi.bmiHeader.biPlanes=1;
  12. bi.bmiHeader.biSize=sizeof(bi.bmiHeader);
  13. bi.bmiHeader.biSizeImage=0;
  14. bi.bmiHeader.biXPelsPerMeter=0;
  15. bi.bmiHeader.biYPelsPerMeter=0;
  16. GetClientRect(hWnd, &tailleFenetre);
  17. SetStretchBltMode(hdc, HALFTONE);
  18. HDC hMemDC= CreateCompatibleDC(hdc);
  19. SetStretchBltMode(hMemDC, HALFTONE);
  20. HBITMAP hBitmap= CreateDIBitmap(hMemDC, &bi.bmiHeader,CBM_INIT,tableau,&bi,DIB_RGB_COLORS);
  21. SelectObject(hMemDC, hBitmap);
  22. StretchBlt(hdc, 0, 0, tailleFenetre.right, tailleFenetre.bottom, hMemDC, 0, 0, tailleX, tailleY, SRCCOPY);
  23. DeleteObject(hBitmap);
  24. DeleteDC(hMemDC);
  25. EndPaint(hWnd, &ps);
  26. break;


 
 
J'ai passé 4 heures sur les forums et à reprendre chaque paramétrage un par un pour essayer de comprendre. J'ai essayé d'intercepter les erreurs (aucun appel à une fonction ne renvoie d'erreur). Je m'attends à avoir la zone centrale de ma fenêtre toute violette (0x00ff00ff) et je me retrouve avec une fenêtre toute noire.  
 
 
Code complet :

Code :
  1. #include "stdafx.h"
  2. #include "Projet test.h"
  3. #define MAX_LOADSTRING 100
  4. #define tailleX 800
  5. #define tailleY 600
  6. // Variables globales :
  7. HINSTANCE hInst;        // instance actuelle
  8. TCHAR szTitle[MAX_LOADSTRING];     // Le texte de la barre de titre
  9. TCHAR szWindowClass[MAX_LOADSTRING];   // le nom de la classe de fenêtre principale
  10. DWORD tableau[tailleX * tailleY];
  11. // Pré-déclarations des fonctions incluses dans ce module de code :
  12. ATOM    MyRegisterClass(HINSTANCE hInstance);
  13. BOOL    InitInstance(HINSTANCE, int);
  14. LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
  15. INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
  16. int APIENTRY _tWinMain(HINSTANCE hInstance,
  17.                      HINSTANCE hPrevInstance,
  18.                      LPTSTR    lpCmdLine,
  19.                      int       nCmdShow)
  20. {
  21. UNREFERENCED_PARAMETER(hPrevInstance);
  22. UNREFERENCED_PARAMETER(lpCmdLine);
  23. for (int i=0;i<tailleX*tailleY;i++) tableau[i]=0x00FF00FF;
  24. MSG msg;
  25. HACCEL hAccelTable;
  26. // Initialise les chaînes globales
  27. LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
  28. LoadString(hInstance, IDC_PROJETTEST, szWindowClass, MAX_LOADSTRING);
  29. MyRegisterClass(hInstance);
  30. // Effectue l'initialisation de l'application :
  31. if (!InitInstance (hInstance, nCmdShow))
  32. {
  33.  return FALSE;
  34. }
  35. hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_PROJETTEST));
  36. // Boucle de messages principale :
  37. while (GetMessage(&msg, NULL, 0, 0))
  38. {
  39.  if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
  40.  {
  41.   TranslateMessage(&msg);
  42.   DispatchMessage(&msg);
  43.  }
  44. }
  45. return (int) msg.wParam;
  46. }
  47. //
  48. //  FONCTION : MyRegisterClass()
  49. //
  50. //  BUT : inscrit la classe de fenêtre.
  51. //
  52. //  COMMENTAIRES :
  53. //
  54. //    Cette fonction et son utilisation sont nécessaires uniquement si vous souhaitez que ce code
  55. //    soit compatible avec les systèmes Win32 avant la fonction 'RegisterClassEx'
  56. //    qui a été ajoutée à Windows 95. Il est important d'appeler cette fonction
  57. //    afin que l'application dispose des petites icônes correctes qui lui sont
  58. //    associées.
  59. //
  60. ATOM MyRegisterClass(HINSTANCE hInstance)
  61. {
  62. WNDCLASSEX wcex;
  63. wcex.cbSize = sizeof(WNDCLASSEX);
  64. wcex.style   = CS_HREDRAW | CS_VREDRAW;
  65. wcex.lpfnWndProc = WndProc;
  66. wcex.cbClsExtra  = 0;
  67. wcex.cbWndExtra  = 0;
  68. wcex.hInstance  = hInstance;
  69. wcex.hIcon   = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_PROJETTEST));
  70. wcex.hCursor  = LoadCursor(NULL, IDC_ARROW);
  71. wcex.hbrBackground = 0;
  72. wcex.lpszMenuName = MAKEINTRESOURCE(IDC_PROJETTEST);
  73. wcex.lpszClassName = szWindowClass;
  74. wcex.hIconSm  = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
  75. return RegisterClassEx(&wcex);
  76. }
  77. //
  78. //   FONCTION : InitInstance(HINSTANCE, int)
  79. //
  80. //   BUT : enregistre le handle de l'instance et crée une fenêtre principale
  81. //
  82. //   COMMENTAIRES :
  83. //
  84. //        Dans cette fonction, nous enregistrons le handle de l'instance dans une variable globale, puis
  85. //        créons et affichons la fenêtre principale du programme.
  86. //
  87. BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
  88. {
  89.    HWND hWnd;
  90.    hInst = hInstance; // Stocke le handle d'instance dans la variable globale
  91.    hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
  92.       CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
  93.    if (!hWnd)
  94.    {
  95.       return FALSE;
  96.    }
  97.    ShowWindow(hWnd, nCmdShow);
  98.    UpdateWindow(hWnd);
  99.    return TRUE;
  100. }
  101. //
  102. //  FONCTION : WndProc(HWND, UINT, WPARAM, LPARAM)
  103. //
  104. //  BUT :  traite les messages pour la fenêtre principale.
  105. //
  106. //  WM_COMMAND - traite le menu de l'application
  107. //  WM_PAINT - dessine la fenêtre principale
  108. //  WM_DESTROY - génère un message d'arrêt et retourne
  109. //
  110. //
  111. LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  112. {
  113. switch (message)
  114. {
  115. case WM_COMMAND:
  116.         int wmId, wmEvent;
  117.  wmId    = LOWORD(wParam);
  118.  wmEvent = HIWORD(wParam);
  119.  // Analyse les sélections de menu :
  120.  switch (wmId)
  121.  {
  122.  case IDM_ABOUT:
  123.   DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
  124.   break;
  125.  case IDM_EXIT:
  126.   DestroyWindow(hWnd);
  127.   break;
  128.  default:
  129.   return DefWindowProc(hWnd, message, wParam, lParam);
  130.  }
  131.  break;
  132. case WM_PAINT:
  133.          {
  134.          PAINTSTRUCT ps;
  135.          HDC hdc=BeginPaint(hWnd, &ps);
  136.          RECT tailleFenetre;
  137.          BITMAPINFO bi;
  138.   bi.bmiHeader.biBitCount=32;
  139.   bi.bmiHeader.biClrImportant=0;
  140.   bi.bmiHeader.biClrUsed=0;
  141.   bi.bmiHeader.biCompression=BI_RGB;
  142.   bi.bmiHeader.biHeight=tailleY;
  143.   bi.bmiHeader.biWidth=tailleX;
  144.   bi.bmiHeader.biPlanes=1;
  145.   bi.bmiHeader.biSize=sizeof(bi.bmiHeader);
  146.   bi.bmiHeader.biSizeImage=0;
  147.   bi.bmiHeader.biXPelsPerMeter=0;
  148.   bi.bmiHeader.biYPelsPerMeter=0;
  149.             GetClientRect(hWnd, &tailleFenetre);
  150.   SetStretchBltMode(hdc, HALFTONE);
  151.             HDC hMemDC= CreateCompatibleDC(hdc);
  152.   SetStretchBltMode(hMemDC, HALFTONE);
  153.   HBITMAP hBitmap= CreateDIBitmap(hMemDC, &bi.bmiHeader,CBM_INIT,tableau,&bi,DIB_RGB_COLORS);
  154.   //HBITMAP hBitmap=CreateCompatibleBitmap(hMemDC, tailleX, tailleY);
  155.   SelectObject(hMemDC, hBitmap);
  156.   SetDIBits(hMemDC, hBitmap, 0, tailleY, tableau, &bi, DIB_RGB_COLORS);
  157.   StretchBlt(hdc, 0, 0, tailleFenetre.right, tailleFenetre.bottom, hMemDC, 0, 0, 15, 15, SRCCOPY);//tailleX, tailleY, SRCCOPY);
  158.             DeleteObject(hBitmap);
  159.             DeleteDC(hMemDC);
  160.   /*
  161.   SetStretchBltMode(hdc, HALFTONE);
  162.   SetBrushOrgEx(hdc, 0, 0, 0);
  163.          
  164.   StretchDIBits(
  165.            hdc,
  166.            0, 0, 640, 480, //tailleFenetre.right, tailleFenetre.bottom,
  167.            0, 0, tailleX, tailleY,
  168.            tableau,
  169.            &bi,
  170.            0,
  171.            0
  172.          );
  173.   */
  174.          EndPaint(hWnd, &ps);
  175.          break;
  176.         }
  177. case WM_DESTROY:
  178.  PostQuitMessage(0);
  179.  break;
  180. default:
  181.  return DefWindowProc(hWnd, message, wParam, lParam);
  182. }
  183. return 0;
  184. }
  185. // Gestionnaire de messages pour la boîte de dialogue À propos de.
  186. INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  187. {
  188. UNREFERENCED_PARAMETER(lParam);
  189. switch (message)
  190. {
  191. case WM_INITDIALOG:
  192.  return (INT_PTR)TRUE;
  193. case WM_COMMAND:
  194.  if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
  195.  {
  196.   EndDialog(hDlg, LOWORD(wParam));
  197.   return (INT_PTR)TRUE;
  198.  }
  199.  break;
  200. }
  201. return (INT_PTR)FALSE;
  202. }


mood
Publicité
Posté le 24-10-2010 à 12:05:03  profilanswer
 

n°2032004
olivthill
Posté le 25-10-2010 à 14:27:44  profilanswer
 

La première chose à corriger est :

bi.bmiHeader.biSizeImage=0;


A la place, il faut écrire :

bi.bmiHeader.biSizeImage = bi.bmiHeader.biWidth * 4 * bi.bmiHeader.biHeight * sizeof(unsigned char);


Je n'ai pas regardé la suite en détail.
 
Edit : J'avais mis "* -1", car d'habitude on met un nombre négatif pour la hauteur pour partir du haut vers le bas, au lieu de l'inverse.


Message édité par olivthill le 25-10-2010 à 14:30:09
n°2032060
tpierron
Posté le 25-10-2010 à 16:25:05  profilanswer
 

Haha, GDI et son API de merde. Bon, quand je fais joujou avec les bitmaps, je préfère utiliser des DIBSection, c'est moins casse gueule. En essayant de modifier ton code, je n'ai pas réussi à le faire fonctionner non plus. Mais en utilisant des DIBSection, ça fonctionne sans problème. Suffit de réécrire ton WM_PAINT de la sorte :

Code :
  1. {
  2.     PAINTSTRUCT ps;
  3.     HDC hdc=BeginPaint(hWnd, &ps);
  4.     RECT tailleFenetre;
  5.     BITMAPINFO bi = {};
  6.  
  7.     bi.bmiHeader.biBitCount=32;
  8.     bi.bmiHeader.biCompression=BI_RGB;
  9.     bi.bmiHeader.biHeight=tailleY;
  10.     bi.bmiHeader.biWidth=tailleX;
  11.     bi.bmiHeader.biPlanes=1;
  12.     bi.bmiHeader.biSize=sizeof(bi.bmiHeader);
  13.  
  14.     GetClientRect(hWnd, &tailleFenetre);
  15.     SetStretchBltMode(hdc, HALFTONE);
  16.  
  17.     HDC hMemDC= CreateCompatibleDC(hdc);
  18.     SetStretchBltMode(hMemDC, HALFTONE);
  19.     LPVOID data;
  20.     HBITMAP hBitmap = CreateDIBSection(hMemDC, &bi,DIB_RGB_COLORS,&data,NULL,0);
  21. //    HBITMAP hBitmap = CreateDIBitmap(hMemDC, &bi.bmiHeader,CBM_INIT,tableau,&bi,DIB_RGB_COLORS);
  22.  
  23.     memcpy(data, tableau, sizeof tableau);
  24.     HANDLE old = SelectObject(hMemDC, hBitmap);
  25.  
  26.     StretchBlt(hdc, 0, 0, tailleFenetre.right, tailleFenetre.bottom, hMemDC, 0, 0, tailleX, tailleY, SRCCOPY);
  27.     BitBlt(hdc, 0, 0, tailleX, tailleY, hMemDC, 0, 0, SRCCOPY);
  28.     SelectObject(hMemDC, old);
  29.     DeleteObject(hBitmap);
  30.     DeleteDC(hMemDC);
  31.  
  32.     EndPaint(hWnd, &ps);
  33.     break;
  34. }


 
Une petite optimisation serait d'allouer le DIBSection avant la boucle d'événement, et d'initialiser le bitmap renvoyé plutôt que d'utiliser une table statique.

n°2032099
borisbaski
Citation personnelle
Posté le 25-10-2010 à 19:57:42  profilanswer
 

@olivthill
Ce champ peut rester à 0. Je cite la MSDN :

Citation :

biSizeImage The size, in bytes, of the image. This may be set to zero for BI_RGB bitmaps.


J'ai essayé, au cas où, de modifier ce champ mais cela n'améliore pas le résultat.
 
@tpierron
Je vais pas me prendre la tête et utiliser les DIBSection, et je vais même utiliser l'amélioration que tu me proposes. N'empêche que sur le principe mon code de départ ne me parait pas si foireux que ça.
Je dis pas que c'est simple de faire une interface graphique qui puisse adapter à tous les matériels, mais le GDI c'est une belle merde.
 
Merci les amis !

n°2032243
olivthill
Posté le 26-10-2010 à 12:32:39  profilanswer
 

Pour infos, voici ma version qui marche, créée en modifiant un peu la version initiale :

Code :
  1. #include <windows.h>
  2. #define MAX_LOADSTRING 100
  3. #define tailleX 800
  4. #define tailleY 600
  5. // Variables globales :
  6. HINSTANCE hInst;        // instance actuelle
  7. // TCHAR szTitle[MAX_LOADSTRING];     // Le texte de la barre de titre
  8. char szTitle[MAX_LOADSTRING];     // Le texte de la barre de titre
  9. // TCHAR szWindowClass[MAX_LOADSTRING];   // le nom de la classe de fenêtre principale
  10. char szWindowClass[MAX_LOADSTRING];   // le nom de la classe de fenêtre principale
  11. DWORD tableau[tailleX * tailleY];
  12. // Pré-déclarations des fonctions incluses dans ce module de code :
  13. ATOM    MyRegisterClass(HINSTANCE hInstance);
  14. BOOL    InitInstance(HINSTANCE, int);
  15. LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
  16. INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
  17. int APIENTRY WinMain(HINSTANCE hInstance,
  18.                      HINSTANCE hPrevInstance,
  19.                      LPTSTR    lpCmdLine,
  20.                      int       nCmdShow)
  21. {
  22. UNREFERENCED_PARAMETER(hPrevInstance);
  23. UNREFERENCED_PARAMETER(lpCmdLine);
  24. for (int i=0;i<tailleX*tailleY;i++) tableau[i]=(DWORD)(0x00FF00FF);
  25. MSG msg;
  26. HACCEL hAccelTable;
  27. // Initialise les chaînes globales
  28. //  ***  LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
  29. strcpy(szTitle, "Test GDI" );
  30. //  *** LoadString(hInstance, IDC_PROJETTEST, szWindowClass, MAX_LOADSTRING);
  31. strcpy(szWindowClass, "Test GDI" );
  32. MyRegisterClass(hInstance);
  33. // Effectue l'initialisation de l'application :
  34. if (!InitInstance (hInstance, nCmdShow))
  35. {
  36. return FALSE;
  37. }
  38. // *** hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_PROJETTEST));
  39. // Boucle de messages principale :
  40. while (GetMessage(&msg, NULL, 0, 0))
  41. {
  42. if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
  43. {
  44.  TranslateMessage(&msg);
  45.  DispatchMessage(&msg);
  46. }
  47. }
  48. return (int) msg.wParam;
  49. }
  50. //
  51. //  FONCTION : MyRegisterClass()
  52. //
  53. //  BUT : inscrit la classe de fenêtre.
  54. //
  55. //  COMMENTAIRES :
  56. //
  57. //    Cette fonction et son utilisation sont nécessaires uniquement si vous souhaitez que ce code
  58. //    soit compatible avec les systèmes Win32 avant la fonction 'RegisterClassEx'
  59. //    qui a été ajoutée à Windows 95. Il est important d'appeler cette fonction
  60. //    afin que l'application dispose des petites icônes correctes qui lui sont
  61. //    associées.
  62. //
  63. ATOM MyRegisterClass(HINSTANCE hInstance)
  64. {
  65.      int i;
  66. WNDCLASSEX wcex;
  67. wcex.cbSize = sizeof(WNDCLASSEX);
  68. wcex.style   = CS_HREDRAW | CS_VREDRAW;
  69. wcex.lpfnWndProc = WndProc;
  70. wcex.cbClsExtra  = 0;
  71. wcex.cbWndExtra  = 0;
  72. wcex.hInstance  = hInstance;
  73. // *** wcex.hIcon   = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_PROJETTEST));
  74. wcex.hIcon   = '\0';
  75. wcex.hCursor  = LoadCursor(NULL, IDC_ARROW);
  76. wcex.hbrBackground = (HBRUSH) COLOR_BACKGROUND;;
  77. // *** wcex.lpszMenuName = MAKEINTRESOURCE(IDC_PROJETTEST);
  78. wcex.lpszMenuName = '\0';
  79. wcex.lpszClassName = szWindowClass;
  80. // *** wcex.hIconSm  = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
  81. // i = RegisterClassEx(&wcex);
  82. return RegisterClassEx(&wcex);
  83. }
  84. //
  85. //   FONCTION : InitInstance(HINSTANCE, int)
  86. //
  87. //   BUT : enregistre le handle de l'instance et crée une fenêtre principale
  88. //
  89. //   COMMENTAIRES :
  90. //
  91. //        Dans cette fonction, nous enregistrons le handle de l'instance dans une variable globale, puis
  92. //        créons et affichons la fenêtre principale du programme.
  93. //
  94. BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
  95. {
  96.    HWND hWnd;
  97.    hInst = hInstance; // Stocke le handle d'instance dans la variable globale
  98. //   hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
  99. //      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
  100.    hWnd = CreateWindowEx(WS_EX_TOOLWINDOW,szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
  101.       CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
  102.    if (!hWnd)
  103.    {
  104.       return FALSE;
  105.    }
  106.    ShowWindow(hWnd, nCmdShow);
  107.    UpdateWindow(hWnd);
  108.    return TRUE;
  109. }
  110. //
  111. //  FONCTION : WndProc(HWND, UINT, WPARAM, LPARAM)
  112. //
  113. //  BUT :  traite les messages pour la fenêtre principale.
  114. //
  115. //  WM_COMMAND - traite le menu de l'application
  116. //  WM_PAINT - dessine la fenêtre principale
  117. //  WM_DESTROY - génère un message d'arrêt et retourne
  118. //
  119. //
  120. LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  121. {
  122. switch (message)
  123. {
  124. case WM_COMMAND:
  125.         int wmId, wmEvent;
  126. wmId    = LOWORD(wParam);
  127. wmEvent = HIWORD(wParam);
  128. // Analyse les sélections de menu :
  129. switch (wmId)
  130. {
  131. #define IDM_ABOUT 101
  132. case 101:
  133. // ***  DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
  134.  break;
  135. #define IDM_EXIT 999
  136. case IDM_EXIT:
  137.  DestroyWindow(hWnd);
  138.  break;
  139. default:
  140.  return DefWindowProc(hWnd, message, wParam, lParam);
  141. }
  142. break;
  143. case WM_PAINT:
  144.          {
  145.          PAINTSTRUCT ps;
  146.          HDC hdc=BeginPaint(hWnd, &ps);
  147.          RECT tailleFenetre;
  148.     BITMAPINFO bi;
  149. bi.bmiHeader.biBitCount=32;
  150.  bi.bmiHeader.biClrImportant=0;
  151.  bi.bmiHeader.biClrUsed=0;
  152.  bi.bmiHeader.biCompression=BI_RGB;
  153.  bi.bmiHeader.biHeight= -tailleY;
  154.  bi.bmiHeader.biWidth=tailleX;
  155.  bi.bmiHeader.biPlanes=1;
  156.  bi.bmiHeader.biSize=sizeof(bi.bmiHeader);
  157. //  bi.bmiHeader.biSizeImage=0;
  158.     bi.bmiHeader.biSizeImage = bi.bmiHeader.biWidth * 4 * bi.bmiHeader.biHeight * sizeof(unsigned char);
  159.  bi.bmiHeader.biXPelsPerMeter=0;
  160.  bi.bmiHeader.biYPelsPerMeter=0;
  161.             GetClientRect(hWnd, &tailleFenetre);
  162. //  SetStretchBltMode(hdc, HALFTONE);
  163.     HDC hMemDC = GetDC(hWnd);
  164. //  SetStretchBltMode(hMemDC, HALFTONE);
  165.  HBITMAP hBitmap= CreateDIBitmap(hMemDC, &bi.bmiHeader,CBM_INIT,tableau,&bi,DIB_RGB_COLORS);
  166.     ReleaseDC(hWnd, hMemDC);
  167.     hMemDC = CreateCompatibleDC(hdc);
  168.  HBITMAP hbmpold = (HBITMAP)SelectObject(hMemDC, hBitmap);
  169. //    BitBlt(hdc, 0, 0,   // dest
  170. //           (int)tailleX, (int)tailleY,
  171. //                hMemDC,        // src
  172. //                0, 0, SRCCOPY);
  173.  StretchBlt(hdc, 0, 0, tailleFenetre.right, tailleFenetre.bottom, hMemDC, 0, 0, tailleX, tailleY, SRCCOPY);
  174.     SelectObject(hMemDC, hbmpold);
  175.     DeleteDC(hMemDC);
  176. //  HBITMAP hBitmap=CreateCompatibleBitmap(hMemDC, tailleX, tailleY);
  177. // SetDIBits(hMemDC, hBitmap, 0, tailleY, tableau, &bi, DIB_RGB_COLORS);
  178. //            DeleteObject(hBitmap);
  179. /*
  180.  SetStretchBltMode(hdc, HALFTONE);
  181.  SetBrushOrgEx(hdc, 0, 0, 0);
  182.          
  183.  StretchDIBits(
  184.            hdc,
  185.            0, 0, 640, 480, //tailleFenetre.right, tailleFenetre.bottom,
  186.            0, 0, tailleX, tailleY,
  187.            tableau,
  188.            &bi,
  189.            0,
  190.            0
  191.          );
  192.          */
  193.          EndPaint(hWnd, &ps);
  194.          break;
  195.         }
  196. case WM_DESTROY:
  197. PostQuitMessage(0);
  198. break;
  199. default:
  200. return DefWindowProc(hWnd, message, wParam, lParam);
  201. }
  202. return 0;
  203. }
  204. // Gestionnaire de messages pour la boîte de dialogue À propos de.
  205. INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  206. {
  207. UNREFERENCED_PARAMETER(lParam);
  208. switch (message)
  209. {
  210. case WM_INITDIALOG:
  211. return (INT_PTR)TRUE;
  212. case WM_COMMAND:
  213. if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
  214. {
  215.  EndDialog(hDlg, LOWORD(wParam));
  216.  return (INT_PTR)TRUE;
  217. }
  218. break;
  219. }
  220. return (INT_PTR)FALSE;
  221. }

n°2032259
gilou
Modérateur
Modzilla
Posté le 26-10-2010 à 13:20:57  profilanswer
 

tpierron a écrit :

Haha, GDI et son API de merde.

Elle est pas particulièrement merdique quand on passe un peu de temps dedans. Mais elle nécessite un peu d'apprentissage. Faut trouver des infos dans des bouquins un peu anciens comme ceux de Martin Heller (Advanced Win32 Programming, etc), mais je ne sais pas si on les trouve encore hors occase.
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2032428
borisbaski
Citation personnelle
Posté le 26-10-2010 à 21:48:29  profilanswer
 

gilou a écrit :

Elle est pas particulièrement merdique quand on passe un peu de temps dedans. Mais elle nécessite un peu d'apprentissage. Faut trouver des infos dans des bouquins un peu anciens comme ceux de Martin Heller (Advanced Win32 Programming, etc), mais je ne sais pas si on les trouve encore hors occase.
A+,


 
Sans doute qu'une bonne doc permet de mieux comprendre le fonctionnement de cet API. Ceci dit, j'ai essayé de comprendre pourquoi le code de olivthill marche et pas le mien. En le remodifiant un peu le code suivant marche :  

Code :
  1. PAINTSTRUCT ps;
  2. HDC hdc=BeginPaint(hWnd, &ps);
  3. RECT tailleFenetre;
  4. BITMAPINFO bi; bi.bmiHeader.biBitCount=32; bi.bmiHeader.biClrImportant=0; bi.bmiHeader.biClrUsed=0; bi.bmiHeader.biCompression=BI_RGB;bi.bmiHeader.biHeight= -tailleY; bi.bmiHeader.biWidth=tailleX;  bi.bmiHeader.biPlanes=1;  bi.bmiHeader.biSize=sizeof(bi.bmiHeader);
  5. bi.bmiHeader.biSizeImage=0;  bi.bmiHeader.biXPelsPerMeter=0;  bi.bmiHeader.biYPelsPerMeter=0;
  6. GetClientRect(hWnd, &tailleFenetre);
  7. HBITMAP hBitmap= CreateDIBitmap(hdc, &bi.bmiHeader,CBM_INIT,tableau,&bi,DIB_RGB_COLORS);
  8. hMemDC = CreateCompatibleDC(hdc);
  9. HBITMAP hbmpold = (HBITMAP)SelectObject(hMemDC, hBitmap);
  10. StretchBlt(hdc, 0, 0, tailleFenetre.right, tailleFenetre.bottom, hMemDC, 0, 0, tailleX, tailleY, SRCCOPY);
  11. SelectObject(hMemDC, hbmpold);
  12. DeleteDC(hMemDC);
  13. EndPaint(hWnd, &ps);


 
Ce qui me porte à croire qu'il faut impérativement exécuter le code 'createDIBitmap' avec le Displau device context cible, et pas avec un memory device context. Pour qui ? pour quoi ? ça... mystère.
 
En tous cas merci les gars!


Aller à :
Ajouter une réponse
 

Sujets relatifs
GDI - Texte transparent sur Form transparentC++ avec GDI+ convertir Tiff compressé LZW en Tiff compressé CCITT4
GDI Bitmat ajout de texteGDI bitmap monochrome->couleur
Gestion de jobs d'impression (GDI)[C# - GDI] Rendre une suite de ligne transparente
[C#] GDI : Redessiner une partie de la fenêtre sur OnPaint[GDI / MFC] Clipping !
[GDI / GDI+] Je craque!!!Charger et afficher des images compréssées avec GDI + MinGW (Dev-cpp)
Plus de sujets relatifs à : GDI


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR