[c/c++] Interface graphique

Interface graphique [c/c++] - C++ - Programmation

Marsh Posté le 14-04-2003 à 20:34:08    

G reussi apres de longue tentative a cree une fenetre.
Dedans g cree des bouton (g trace des rectangle et je verifie ou ce situe la souris et si l'utilisateur clique). Une fois qu' l'utilisateur clique sur un de ces bouton, je voudrais redessiner la fenetre. Comment puis-je faire pour effacer la fenetre et en redessiner une autre en fonction du bouton qui a été cliqué.
 
Est il possible de repasser par WM_PAINT. En fait lorsque je clique sur l'un des boutons, g un booleen et en fonction de ce booleen je veux dessiner des choses differentes ( g essayer avec :
 
RedrawWindow();
UpdateWindow();
 

Code :
  1. case WM_PAINT :
  2.          if (bool == true)
  3.          {
  4.                 ......
  5.          }
  6.          else
  7.              .....
  8.          break;


 
Merci


Message édité par touxe le 14-04-2003 à 20:34:35
Reply

Marsh Posté le 14-04-2003 à 20:34:08   

Reply

Marsh Posté le 14-04-2003 à 21:16:39    

Salut,
 
Si j'ai bien compris bool est une variable, et tu es en C car bool est un mot réservé en C++.  :sarcastic:  

Code :
  1. if (bool == true)


 
Donc, si tu gére toi même tes boutons, il te faut bien passé par l'evenement WM_PAINT, car c'est lui qui appelé quand une partie de la fenêtre doit être affiché. Ce qui peut être provoqué manuellement par InvalidateRect.

Code :
  1. HDC hDc ;    // contexte de peripherique
  2. PAINTSTRUCT ps ;  // attributs relatif a l'affichage de la fenetre
  3. ...
  4. // on doit afficher la fenetre
  5. case WM_PAINT :
  6. // recuperer le contexte de peripherique de la fenetre
  7. hDc = BeginPaint (hWnd, &ps) ;
  8. // ton dessin suivant le 'bool'
  9. ...
  10. // on a finit d'afficher la fenetre
  11. EndPaint (hWnd, &ps) ;
  12. return 0 ;


Donc, il te faut juste modifier bool selon l'evenement que tu veux traiter, WM_LBUTTONDOWN je presume, en utilsant InvalidateRect plutot que RedrawWindow() ou UpdateWindow().
Si tu veux eviter les scintillement, il faut utiliser un DC mémoire et utiliser InvalidateRect avec FALSE en dernier parametre.
 
Tu peux aussi créer une fenêtre enfant, et en faire un bouton personalisé...


Message édité par Poireau le 14-04-2003 à 21:20:22
Reply

Marsh Posté le 14-04-2003 à 22:14:37    

touxe a écrit :

G reussi apres de longue tentative a cree une fenetre.
Dedans g cree des bouton (g trace des rectangle et je verifie ou ce situe la souris et si l'utilisateur clique).


 
faudrait eviter ce genre de choses normalement, tester les coordonnées de la souris pour savoir ou l'utilisateur clique. Si tu as des controles pré-définis (a savoir 'button';), c'est pas pour rien. tu les fais ownerdraw, tu traces 'tes rectangles' en interceptant wm_drawitem, et apres qd l'utilisateur clique dessus, c'est géré tout seul.
 
enfin bon, si t'as commencé comme ca et que tu t'en sors, je vais pas te forcer a tout recommencer.
 
sur ce, bonne lutte... (au moins ca t'apprendra le win32)

Reply

Marsh Posté le 15-04-2003 à 00:16:41    

Merci Poireau.
 
G fait ce que tu as dis mais g l'impression que ma fenetre n'est pas mis a jours mais tt les autres fenetre qui sont derrier ou meme le bureau de windows le sont!!
 
g appeler mas fonction comme ceci et c dans  
case WM_LBUTTONDOWN:
 
InvalidateRect(NULL, NULL, FALSE);
 
Konar merci a toi aussi mais g pas tout compris :)
 
Si ca peut etre utile voila le code
 

Code :
  1. LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  2. {
  3. int i, tmp, annuler = 0, reserver = 0, j = 0;
  4. int xpos,ypos;
  5. static int adresse, taille;
  6. static BOOL cadre_ant=FALSE, cadre_alloue=FALSE, cadre_libere=FALSE;
  7. TCHAR buff_taille[15],buff_taille2[15], buff_adresse[15], buff_tmp[15];
  8. PTCHAR sztemp;
  9. int wmId, wmEvent;
  10. PAINTSTRUCT ps;
  11. HDC hdc;
  12. static HPEN hpen1,hpen2;
  13. static HBRUSH hbrush;
  14. static HWND hwndEdit[3];
  15. static HWND hwndbutton[3];
  16. static int pos[6] = {450,100,630,50,630,100};
  17. switch (message)
  18. {
  19. case WM_CREATE: //boite de texte
  20.  hpen1 = CreatePen(PS_SOLID,1,RGB(255,0,0));
  21.  hpen2 = CreatePen(PS_SOLID,1,RGB(128,128,128));
  22.  hbrush = CreateHatchBrush(HS_BDIAGONAL, RGB(0,0,255));
  23.  if ( (reserver == 0) && (annuler == 0))
  24.  {
  25.  }
  26.  else
  27.   if (reserver == 1)
  28.   {
  29.    // cree les boites
  30.    hwndEdit[0] = CreateWindow(TEXT("edit" ),//creation
  31.    NULL,         // parametre
  32.    WS_CHILD|WS_VISIBLE|WS_BORDER,
  33.    50,
  34.    150,
  35.    100,
  36.    20,
  37.    hWnd,
  38.    (HMENU)0,
  39.    ((LPCREATESTRUCT)lParam)->hInstance,NULL);
  40.    hwndEdit[1] = CreateWindow(TEXT("edit" ),//creation
  41.    NULL,         // parametre
  42.    WS_CHILD|WS_VISIBLE|WS_BORDER,
  43.    230,
  44.    150,
  45.    100,
  46.    20,
  47.    hWnd,
  48.    (HMENU)1,
  49.    ((LPCREATESTRUCT)lParam)->hInstance,NULL);
  50.    // cree les boutons valider
  51.    hwndbutton[0] = CreateWindow(TEXT("button" ),
  52.    TEXT("VALIDER" ),
  53.    WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,
  54.    450,
  55.    150,
  56.    65,
  57.    20,
  58.    hWnd,
  59.    (HMENU)0+3,
  60.    ((LPCREATESTRUCT)lParam)->hInstance,NULL);
  61.   }
  62.   else
  63.    if (annuler == 1)
  64.    {
  65.     hwndEdit[0] = CreateWindow(TEXT("edit" ),//creation
  66.     NULL,         // parametre
  67.     WS_CHILD|WS_VISIBLE|WS_BORDER,
  68.     50,
  69.     150,
  70.     100,
  71.     20,
  72.     hWnd,
  73.     (HMENU)0,
  74.     ((LPCREATESTRUCT)lParam)->hInstance,NULL);
  75.     hwndEdit[1] = CreateWindow(TEXT("edit" ),//creation
  76.     NULL,         // parametre
  77.     WS_CHILD|WS_VISIBLE|WS_BORDER,
  78.     230,
  79.     150,
  80.     100,
  81.     20,
  82.     hWnd,
  83.     (HMENU)1,
  84.     ((LPCREATESTRUCT)lParam)->hInstance,NULL);
  85.    }
  86.  return 0;
  87. case WM_COMMAND:
  88.  wmId    = LOWORD(wParam);
  89.  wmEvent = HIWORD(wParam);
  90.  // Parse the menu selections:
  91.  switch (wmId)
  92.  {
  93.  case IDM_ABOUT:
  94.   DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
  95.   break;
  96.  case IDM_INITIALISATION:
  97.   //DialogBox(hInst, (LPCTSTR)IDD_DIALOG_ALGO, hWnd, (DLGPROC)menu_algo);
  98.   break;
  99.  case IDM_EXIT:
  100.   DestroyWindow(hWnd);
  101.   break;
  102.  case 12:  // Bouton OK de gauche
  103.   err = FALSE;
  104.   GetWindowText(hwndEdit[0], buff_taille, 15);
  105.   GetWindowText(hwndEdit[1], buff_taille2, 15);
  106.     SetWindowText(hwndEdit[0], TEXT("" ));
  107.     SetWindowText(hwndEdit[1], TEXT("" ));
  108.     strcat(buff_taille, " " );
  109.     strcat(buff_taille, buff_taille2);
  110.     tmp = wsprintf(buff_tmp, "Nom du client : %s", buff_taille);
  111.     hdc = GetDC(hWnd);
  112.     SetTextColor(hdc,0x00000000);
  113.     TextOut(hdc, 60, 190, buff_tmp, tmp);
  114.     aff_etat(hdc);
  115.     aff_bar(hdc, hbrush);
  116.     xpos = 20+adresse*760/TAILLE_MEM;
  117.     MoveToEx(hdc, xpos, 450, NULL);
  118.     SelectObject(hdc, hpen1);
  119.     ReleaseDC(hWnd, hdc);
  120.   if (err)
  121.    MessageBox(hWnd, tab_err[-err], TEXT("ERREUR" ), MB_ICONERROR);
  122.   break;
  123.  }
  124.  case WM_PAINT:
  125.   hdc = BeginPaint(hWnd, &ps);
  126.   if ( (reserver == 0) && (annuler == 0))
  127.   {
  128.     SetTextColor(hdc,0x00008000);
  129.     RoundRect(hdc,290,5,470,35,16,16);
  130.     TextOut(hdc,302,10,TEXT("AEROPORT DE L'EFREI" ),19);
  131.     RoundRect(hdc,5,55,180,80,16,16);
  132.     SelectObject(hdc, GetStockObject(NULL_BRUSH));
  133.     TextOut(hdc,20,59,TEXT("RESERVER UN BILLET" ),18);
  134.     RoundRect(hdc,180,55,355,80,16,16);
  135.     TextOut(hdc,195,59,TEXT("ANNULER UN BILLET" ),17);
  136.     SelectObject(hdc, GetStockObject(LTGRAY_BRUSH));
  137.     Rectangle(hdc,-1,525,800,555);
  138.     TextOut(hdc, 60, 190+5*j, "ICI", 3);
  139.     j++;
  140.   }
  141.   else
  142.    if (reserver == 1)
  143.    {
  144.     //SetBkColor(hdc, NULL);
  145.     SetTextColor(hdc,0x00008000);
  146.     RoundRect(hdc,290,5,470,35,16,16);
  147.     TextOut(hdc,302,10,TEXT("RESERVATION" ),11);
  148.     RoundRect(hdc,5,55,180,80,16,16);
  149.     SelectObject(hdc, GetStockObject(NULL_BRUSH));
  150.     TextOut(hdc,20,59,TEXT("RESERVER UN BILLET" ),18);
  151.     RoundRect(hdc,180,55,355,80,16,16);
  152.     TextOut(hdc,195,59,TEXT("ANNULER UN BILLET" ),17);
  153.     SetTextColor(hdc,0x00000000);
  154.     TextOut(hdc,5,151,TEXT("Nom :" ),5);
  155.     TextOut(hdc,168,151,TEXT("Prenom :" ),8);
  156.     SelectObject(hdc, GetStockObject(LTGRAY_BRUSH));
  157.     Rectangle(hdc,-1,525,800,555);
  158.    }
  159.    else
  160.     if ( annuler == 1)
  161.     {
  162.     SetTextColor(hdc,0x00008000);
  163.     RoundRect(hdc,290,5,470,35,16,16);
  164.     TextOut(hdc,302,10,TEXT("ANNULATION" ),10);
  165.     RoundRect(hdc,5,55,180,80,16,16);
  166.     SelectObject(hdc, GetStockObject(NULL_BRUSH));
  167.     TextOut(hdc,20,59,TEXT("RESERVER UN BILLET" ),18);
  168.     RoundRect(hdc,180,55,355,80,16,16);
  169.     TextOut(hdc,195,59,TEXT("ANNULER UN BILLET" ),17);
  170.     SetTextColor(hdc,0x00000000);
  171.     TextOut(hdc,5,151,TEXT("Nom :" ),5);
  172.     TextOut(hdc,168,151,TEXT("Prenom :" ),8);
  173.     SelectObject(hdc, GetStockObject(LTGRAY_BRUSH));
  174.     Rectangle(hdc,-1,525,800,555);
  175.    }
  176.   EndPaint(hWnd, &ps);
  177.   break;
  178.  case WM_MOUSEMOVE:
  179.   xpos = LOWORD(lParam);  // horizontal position of cursor  
  180.   ypos = HIWORD(lParam);  // vertical position of cursor  
  181. {
  182.    hdc = GetDC(hWnd);
  183.    SelectObject(hdc,GetStockObject(NULL_BRUSH));
  184.    if ((xpos>=5) && (xpos<=180) && (ypos>=55) && (ypos<=80)) {
  185.     SelectObject(hdc, GetStockObject(HOLLOW_BRUSH));
  186.     SetBkColor(hdc, 0xC2C2C2);
  187.     for (i=0; i<300; i++)
  188.      TextOut(hdc,5+i,530,TEXT(" " ),1);
  189.      SelectObject(hdc, GetStockObject(WHITE_BRUSH));
  190.      SetBkColor(hdc, 0xFFFFFF);
  191.      SetTextColor(hdc,0x00008000);
  192.      RoundRect(hdc,180,55,355,80,16,16);
  193.      TextOut(hdc,195,59,TEXT("ANNULER UN BILLET" ),17);
  194.      SelectObject(hdc, GetStockObject(LTGRAY_BRUSH));
  195.      SetBkColor(hdc, 0xC2C2C2);
  196.      RoundRect(hdc,5,55,180,80,16,16);
  197.      TextOut(hdc,20,59,TEXT("RESERVER UN BILLET" ),18);
  198.      SetTextColor(hdc,0x000000FF);
  199.      TextOut(hdc,5,530,TEXT("Cliquez ICI pour reserver un billet :" ),35);
  200.    // }
  201.    }
  202.    else
  203.     if ((xpos>=180) && (xpos<=355) && (ypos>=55) && (ypos<=80)) {
  204.      SetBkColor(hdc, 0xC2C2C2);
  205.      for (i=0; i<300; i++)
  206.       TextOut(hdc,5+i,530,TEXT(" " ),1);
  207.      SetBkColor(hdc, 0xFFFFFF);
  208.      SelectObject(hdc, GetStockObject(WHITE_BRUSH));
  209.      RoundRect(hdc,5,55,180,80,16,16);
  210.      SetTextColor(hdc,0x00008000);
  211.      TextOut(hdc,20,59,TEXT("RESERVER UN BILLET" ),18);
  212.      SelectObject(hdc, GetStockObject(LTGRAY_BRUSH));
  213.      SetBkColor(hdc, 0xC2C2C2);
  214.      RoundRect(hdc,180,55,355,80,16,16);
  215.      TextOut(hdc,195,59,TEXT("ANNULER UN BILLET" ),17);
  216.      SetTextColor(hdc,0x000000FF);
  217.      TextOut(hdc,5,530,TEXT("Cliquez ICI pour annuler un billet :" ),35);
  218.    // }
  219.     }
  220.    else {
  221.     if (cadre_alloue==FALSE) {
  222.      SetBkColor(hdc, 0xC2C2C2);
  223.      for (i=0; i<300; i++)
  224.       TextOut(hdc,5+i,530,TEXT(" " ),1);
  225.      SetBkColor(hdc, 0xFFFFFF);
  226.      SelectObject(hdc, GetStockObject(WHITE_BRUSH));
  227.      RoundRect(hdc,5,55,180,80,16,16);
  228.      SetTextColor(hdc,0x00008000);
  229.      TextOut(hdc,20,59,TEXT("RESERVER UN BILLET" ),18);
  230.      RoundRect(hdc,180,55,355,80,16,16);
  231.      TextOut(hdc,195,59,TEXT("ANNULER UN BILLET" ),17);
  232.     }
  233.    }
  234.    ReleaseDC(hWnd,hdc);
  235.   }
  236.   break;
  237.  case WM_LBUTTONDOWN:
  238.   xpos = LOWORD(lParam);  // horizontal position of cursor  
  239.   ypos = HIWORD(lParam);  // vertical position of cursor  
  240.   {
  241.    hdc = GetDC(hWnd);
  242.    SelectObject(hdc,GetStockObject(NULL_BRUSH));
  243.    if ((xpos>=5) && (xpos<=180) && (ypos>=55) && (ypos<=80))
  244.    {
  245.     SelectObject(hdc, GetStockObject(HOLLOW_BRUSH));
  246.     SetBkColor(hdc, 0xC2C2C2);
  247.     for (i=0; i<300; i++)
  248.      TextOut(hdc,5+i,530,TEXT(" " ),1);
  249.     TextOut(hdc,5,530,TEXT("L'utilisateur a clique sur Reserver :" ),35);
  250.     annuler = 0;
  251.     reserver = 1;
  252.     InvalidateRect(NULL, NULL, FALSE);
  253.    }
  254.    else
  255.     if ((xpos>=180) && (xpos<=355) && (ypos>=55) && (ypos<=80))
  256.     {
  257.      SetBkColor(hdc, 0xC2C2C2);
  258.      for (i=0; i<300; i++)
  259.       TextOut(hdc,5+i,530,TEXT(" " ),1);
  260.     TextOut(hdc,5,530,TEXT("L'utilisateur a clique sur Annuler :" ),35);
  261.     annuler = 1;
  262.     reserver = 0;
  263.     InvalidateRect(NULL, NULL, FALSE);
  264.     }
  265.   }
  266.   break;
  267.  case WM_DESTROY:
  268.   DeleteObject(hpen1);
  269.   DeleteObject(hpen2);
  270.   DeleteObject(hbrush);
  271.   PostQuitMessage(0);
  272.   break;
  273.  default:
  274.   return DefWindowProc(hWnd, message, wParam, lParam);
  275.    }
  276.    return 0;
  277. }


 
Et ca si ca peut aider a comprendre ce que je fais :)
 
http://efraide.levillage.org/files/aeroprt.JPG


Message édité par touxe le 15-04-2003 à 00:33:00
Reply

Marsh Posté le 15-04-2003 à 18:43:41    

Ok, tu utilise mal la fonction InvalidateRect, car tu lui passe NULL en premier argument, alors qu'il faut indentifier la fenetre a rafraîchir. Et tu dispose de l'indentifiant de la fenetre le Handle Window :

Code :
  1. LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  2. ...
  3. // faut faire :
  4. InvalidateRect(hWnd, NULL, FALSE);
  5. // au lieu
  6. InvalidateRect(NULL, NULL, FALSE);
  7. // ou encore mieux avec rect qui est la partie de la fenetre a rafraichir
  8. InvalidateRect(hWnd, &rect, FALSE);


 
Le fait de ne pas mettre d'identifiant permet de rafraîchir le bureau.
 
Sinon vu la longueur de ton code, la solution de Konar qui consiste a traiter les WM_DRAWITEM est plus propre, et plus simple a lire.
Tu aurais juste a créer une boîte de dialogue avec tes boutons et tes edit boxes, et modifier leur affichage.
Mais bon, comme tu es parti sur ta méthode...

Reply

Marsh Posté le 15-04-2003 à 18:53:52    

Ca ne veut pas marcher :) je sais pas pourquoi. Soit la fenetre n'est pas effacer soit il passe toujours dans la meme chose pour le WM_PAINT.
 
G l'impression qu'il efface juste le cadre du bouton.
 
L'appel de InvalidateRect est il bien placé ?
 
Peut etre une idee est ce que il garde mes variable annuler et reserver apres l'appel de invalidate ? si il ne les garde pas et qu'il les reinitialise c  normal qu'il dessine la meme chose.
 
C bon ca marche mais je suis obliger de mettre les variable annuler et reserver (ma bool) en global


Message édité par touxe le 15-04-2003 à 19:13:20
Reply

Marsh Posté le 15-04-2003 à 21:47:09    

Essaye alors

Code :
  1. InvalidateRect (hWnd, NULL, TRUE) ;


Ca permt d'effacer avant de reafficher, mais ça a la facheuse tendance à faire des scintillements...

Reply

Marsh Posté le 15-04-2003 à 21:57:18    

Euh, j'avais pas trop lu ton code, mais le code de dessin dans le traitement de l'evenement WM_LBUTTONDOWN n'est pas approprié...
En effet, seul la procédure WM_PAINT doit dessiner, donc il te faut positionner une variable dans le traitement de l'evenement WM_LBUTTONDOWN. Et changer l'affichage selon cette variable, ce qui sera fait via InvalidateRect (hWnd, NULL, FALSE), car il transmet un evenement WM_PAINT...
Pareil dans WM_MOUSEMOVE.
 
En fait, ce n'est pas faux de dessiner dans un autre evenement que WM_PAINT, mais le dessin sera efface si une fenetre passe au dessus par exemple. Alors que si tu utilise WM_PAINT, le systeme se charge d'envoyer l'evenement WM_PAINT, et donc ca ce reaffichera. InvalidateRect permet de forcer cette affichage...

Reply

Marsh Posté le 15-04-2003 à 22:38:26    

Ok merci je commence a piger le truc !
Est ce que il y a une fonction qui renvoit un WM_CREATE car qd je v cliquer sur l'un des bouton et afficher ma page correspondante je voudrais cree des edit box pour recevoir les nom, prenom etc ...
 
Merci

Reply

Marsh Posté le 15-04-2003 à 23:07:34    

touxe a écrit :

Ok merci je commence a piger le truc !
Est ce que il y a une fonction qui renvoit un WM_CREATE car qd je v cliquer sur l'un des bouton et afficher ma page correspondante je voudrais cree des edit box pour recevoir les nom, prenom etc ...
 
Merci


Oui, c'est CreateWindow   :ange: ...
C'est le premier évenement que reçoit la fenêtre.
 
Mais sinon, tu peut provoquer manuellement les évenements, avec SendMessage ou PostMessage.

Reply

Marsh Posté le 15-04-2003 à 23:07:34   

Reply

Marsh Posté le 15-04-2003 à 23:19:21    

Donc si je veux cree mes editbox pendant que je redessine la fenetre je fais invalidaterectangle et sendmessage(WM_CREATE)
 
(je comprend pas les parametre de SendMessage )
 
g fait ca en fait mais forcement c une erreur ;)
 

Code :
  1. case WM_LBUTTONDOWN:
  2.   xpos = LOWORD(lParam);  // horizontal position of cursor  
  3.   ypos = HIWORD(lParam);  // vertical position of cursor  
  4.   {
  5.    hdc = GetDC(hWnd);
  6.    SelectObject(hdc,GetStockObject(NULL_BRUSH));
  7.    if ((xpos>=5) && (xpos<=180) && (ypos>=55) && (ypos<=80))
  8.    {
  9.     SelectObject(hdc, GetStockObject(HOLLOW_BRUSH));
  10.     SetBkColor(hdc, 0xC2C2C2);
  11.     for (i=0; i<300; i++)
  12.      TextOut(hdc,5+i,530,TEXT(" " ),1);
  13.     TextOut(hdc,5,530,TEXT("L'utilisateur a clique sur Reserver :" ),35);
  14.     if ( reserver != 1 )
  15.     {
  16.      annuler = 0;
  17.      reserver = 1;
  18.      InvalidateRect(hWnd, NULL, TRUE);
  19.      SendMessage(hWnd, WM_CREATE, NULL, NULL);
  20.     }
  21.    }


 
Le WM_CREATE est le meme que ds le message precedent.
 
Une fois que j'aurais reussi a cree ces edite box (hwndEdit) si je dois changer de page (l'utilisateur clique sur l'un des boutons) faut il detruir ces editebox et si oui comment )
 
Je crois que ce sera mes dernieres questions :) tous commencant a bien prendre forme
 
Merci


Message édité par touxe le 15-04-2003 à 23:56:13
Reply

Marsh Posté le 16-04-2003 à 13:36:06    


    Salut, j'aimerais juste savoir avec quel librairie vous faites ce genre de programmation ??? Vous utiliser SDL ???
 

Reply

Marsh Posté le 16-04-2003 à 13:38:12    

Joey_Joe a écrit :


    Salut, j'aimerais juste savoir avec quel librairie vous faites ce genre de programmation ??? Vous utiliser SDL ???
 
 

Non, c'est du GDI tout simple


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 16-04-2003 à 13:45:40    


    Ouais, ca marche comment ? Tu fais un #include quoi au début ?

Reply

Marsh Posté le 16-04-2003 à 13:48:15    

Joey_Joe a écrit :


    Ouais, ca marche comment ? Tu fais un #include quoi au début ?
 


 
En général, c'est Winuser.h et Windows.h


---------------
"Dieu a exploité tous nos complexes d'infériorité, en commençant par notre incapacité de croire à notre propre divinité." - Emil Michel Cioran
Reply

Marsh Posté le 16-04-2003 à 15:16:32    

touxe a écrit :

Donc si je veux cree mes editbox pendant que je redessine la fenetre je fais invalidaterectangle et sendmessage(WM_CREATE)
 
(je comprend pas les parametre de SendMessage )


 
J'ai répondu à ta question précédente sans me soucier de ta manière d'organiser le code, à savoir si on pouvait générer l'évenement WM_CREATE. Oui, c'est possible, mais c'est pas propre.
L'évenement WM_CREATE doit correspondre uniquement au traitement de la création de le fenêtre, c'est à dire ici créer "objets" : les boutons,...
 
Donc, pour aller dans ta vision des choses, pour créer des objets suivant le clic de la souris, tu as deux possibilités plus propre.
La première est de créer l'objet avec un CreateWindow(...) dans l'evenement WM_LBUTTONDOWN ce qui donne un truc du genre :

Code :
  1. case WM_LBUTTONDOWN:
  2.      xpos = LOWORD(lParam);  // horizontal position of cursor   
  3.      ypos = HIWORD(lParam);  // vertical position of cursor   
  4.      {
  5.         // faut pas dessiner ici, pas bien  ;(
  6.         //hdc = GetDC(hWnd);
  7.         //SelectObject(hdc,GetStockObject(NULL_BRUSH));
  8.    
  9.         if ((xpos>=5) && (xpos<=180) && (ypos>=55) && (ypos<=80)) 
  10.         {
  11.    // faut pas dessiner ici non plus  ;(
  12.            //SelectObject(hdc, GetStockObject(HOLLOW_BRUSH));
  13.            //SetBkColor(hdc, 0xC2C2C2);
  14.            //for (i=0; i<300; i++)
  15.            // TextOut(hdc,5+i,530,TEXT(" " ),1);
  16.      
  17.            //TextOut(hdc,5,530,TEXT("L'utilisateur a clique sur Reserver :" ),35);
  18.            if ( reserver != 1 )
  19.            {
  20.               annuler = 0;
  21.               reserver = 1;
  22.               // tu cree ton objet hObjet qui est une variable globale (statique)
  23.               hObjet = CreateWindow (...) ;
  24.            }
  25.            // on provoque le rafraichissement de la fenetre entiere
  26.            // traitement de WM_PAINT selon les variables reserver, annuler ici
  27.            InvalidateRect(hWnd, NULL, TRUE);
  28.         }


 
La deuxième est je pense la plus simple à faire et surtout à lire, c'est de créer tous les objets dont tu as besoin dans WM_CREATE à l'aide de CreateWindow.
Le problème est qu'ils seront tous affichés, la solution est de les caché tant que l'on en a pas besoin.
Pour cela tu peux positionner un indicateur à la création de la fenêtre enfant, ou bien utiliser la fonction ShowWindow :

Code :
  1. // cacher la fenetre enfant
  2. ShowWindow (hFenEnfant, SW_HIDE) ;
  3. // reafficher la fenetre normalement
  4. ShowWindow (hFenEnfant, SW_SHOW) ;

Reply

Marsh Posté le 16-04-2003 à 15:52:31    

Ok g choisie la deuxieme solution ca marche bien ! merci
 
Pour l'instant pas d'autres question :)
 
Merci pour toutes ton aide

Reply

Marsh Posté le 16-04-2003 à 16:09:53    

touxe a écrit :

Ok g choisie la deuxieme solution ca marche bien ! merci
 
Pour l'instant pas d'autres question :)
 
Merci pour toutes ton aide


No pb  :)
 
C'est dans ces moments que l'on se rend compte que l'API Win32 et la msdn, sont compliquées, mal faites, mais somme toute puissante...

Reply

Marsh Posté le 16-04-2003 à 16:15:56    

Ca aura été rapide ma periode sans question :)
J'arrive tres bien maintenat a traiter ce que l'utilisateur ecrit dans les editBox masi comment effacer ce qui est dedans ?
Car qd je passe d'une fenetre a l'autre (annuler ou reserver) sans valider mes reponses, le texte reste.
Quand je valide ma reponse, je traite ce qui est ecrit et je le reaffiche et la le texte s'efface je suppise grace a ReleaseDC.
 

Code :
  1. case 3:  // Bouton OK de gauche
  2.   err = FALSE;
  3.   GetWindowText(hwndEdit[0], buff_taille, 15);
  4.   GetWindowText(hwndEdit[1], buff_taille2, 15);
  5.   GetWindowText(hwndEdit[2], buff_taille3, 15);
  6.   SetWindowText(hwndEdit[0], TEXT("" ));
  7.   SetWindowText(hwndEdit[1], TEXT("" ));
  8.   SetWindowText(hwndEdit[2], TEXT("" ));
  9.   strcat(buff_taille, " " );
  10.   strcat(buff_taille, buff_taille2);
  11.   strcat(buff_taille, " avec pour N° de Téléphone : " );
  12.   strcat(buff_taille, buff_taille3);
  13.   tmp = wsprintf(buff_tmp, "Nom du client : %s", buff_taille);
  14.   hdc = GetDC(hWnd);
  15.   SetTextColor(hdc,0x00000000);
  16.   TextOut(hdc, 60, 240, buff_tmp, tmp);
  17.   SelectObject(hdc, hpen1);
  18.   ReleaseDC(hWnd, hdc);


 
Seulement si j'essai de faire la meme chose dans WM_LBUTTONDOWN il ne se passe rien.
 
Au fait aurais tu un site qui explique tout ca. Ca eviterais de t'embetter :)
 
MErci

Reply

Marsh Posté le 16-04-2003 à 17:06:32    

Pour effacer une edit box faut utiliser comme tu fais un SetWindowText (hEdit, "" ) ;
 
A part ça, je vois pas bien d'où vient ton problème, il faudrait que tu décompose la WndProc, en procedure que tu appelles, ce serait bien plus lisible.
Et aussi d'afficher le code en entier.
 
Si tu dessinais que dans WM_PAINT, tu trouverais plus facilement le problème.
 
Pour des sites :
http://www.developpez.com/
http://www.winprog.org
http://www.programmationworld.com
http://win32.planet-d.net

Reply

Marsh Posté le 16-04-2003 à 21:08:20    

Merci tout marche parfaitement bien.
Je m'aataque a des petits truc pour ameliorer le programme.
G une COMBOBOX comment faire pour selectionner par defaut un item. Car ma COMBOBOX qd elle est afficher n'a aucun texte, il faut cliquer dessus pour voir les differents choix.
 
G cru comprendre ne cherchant ds la MSDN qu'il fallait utiliser envoyer comme message WM_DRAWITEM mais je comprend pas le parametre "lpdis = (LPDRAWITEMSTRUCT) lParam"  
 
lpdis  
Value of lParam. Pointer to a DRAWITEMSTRUCT structure containing information about the item to be drawn and the type of drawing required.

 
Je ne comprend pas l'utilisation de la structure DRAWITEMSTRUCT.
 
Voila ce que g essayer de faire mais ca a pas l'aire de marcher
 

Code :
  1. DRAWITEMSTRUCT dis;
  2. ...
  3. dis.CtlType = ODT_COMBOBOX;
  4.      dis.CtlID = 0;
  5.      dis.itemID = 0;
  6.      dis.itemAction = ODA_DRAWENTIRE;
  7.      dis.itemState = ODS_CHECKED;
  8.      dis.hwndItem = hwndliste[0];
  9.      dis.hDC = hdc;
  10.      dis.itemData = 0L;
  11.      SendMessage(hwndliste[0],WM_DRAWITEM,0,(LONG)&dis);


Message édité par touxe le 16-04-2003 à 21:31:04
Reply

Marsh Posté le 16-04-2003 à 21:32:42    

touxe a écrit :

Merci tout marche parfaitement bien.
Je m'aataque a des petits truc pour ameliorer le programme.
G une COMBOBOX comment faire pour selectionner par defaut un item. Car ma COMBOBOX qd elle est afficher n'a aucun texte, il faut cliquer dessus pour voir les differents choix.
 
G cru comprendre ne cherchant ds la MSDN qu'il fallait utiliser envoyer comme message WM_DRAWITEM mais je comprend pas le parametre "lpdis = (LPDRAWITEMSTRUCT) lParam"  
 
lpdis  
Value of lParam. Pointer to a DRAWITEMSTRUCT structure containing information about the item to be drawn and the type of drawing required.

 
Je ne comprend pas l'utilisation de la structure DRAWITEMSTRUCT.


Hum, DRAWITEMSTRUCT, c'est ce dont parlais Konar en debut de post, c'est pour gérer l'affichage du combo. C'est pas ce qui nous intéresse ici...
 
Il suffi juste après avoir créer et rempli la combobox, de sélectionner une ligne :

Code :
  1. // selectionne la ligne iLigne
  2. SendMessage (hCombo, CB_SETCURSEL, (WPARAM) iLigne, 0) ;


Reply

Marsh Posté le 16-04-2003 à 21:43:56    

hé he je l'avais pas vu celui la :) pourtant je l'ai epluché la MSDN :)

Reply

Marsh Posté le 18-04-2003 à 00:04:21    

Allé ! je revient a l'attaque !!!
 
J'aimerais integrer des image dans mon logiciel maintenant. Comment faut il faire ? est il possible de les caché a certain moment et de les montre a d'autre comme tu m'as fait faire pour les editbox avec la fonction ShowWindows.
 
Merci

Reply

Marsh Posté le 18-04-2003 à 01:12:37    

Tu peux utiliser un static (style SS_BITMAP).
Pareil, tu le créé sans WS_VISIBLE.
Puis tu le montre / cache avec ShowWindow.


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
Reply

Marsh Posté le 18-04-2003 à 18:21:49    

qqn pourrais m'aider, je ne comprend pas les parametre de cette fonction. J'arrive a afficher mes image mais je verifie a chaque fois si elle est bien place en changeant sans comprendre les parametre
 

Code :
  1. BOOL BitBlt(
  2. HDC hdcDest, // handle du contexte de périphérique de destination  
  3. int nXDest,  // coordonnée x de destination du rectangle supérieur gauche du bitmap
  4. int nYDest,  // idem pour y
  5. int nWidth,  // largeur du bitmap (destination et source)
  6. int nHeight,  // hauteur du bitmap (destination et source)
  7. HDC hdcSrc,  // handle du contexte de périphérique source
  8. int nXSrc,  // coordonnée x source du rectangle supérieur gauche du bitmap
  9. int nYSrc,  // idem pour y
  10. DWORD dwRop  // code d'opération de trame (pour quelques manipulations)
  11.   );


 
Mon probleme c pour les coordonnée je pige pas la difference
 
Merci


Message édité par touxe le 18-04-2003 à 18:22:27
Reply

Marsh Posté le 18-04-2003 à 19:06:23    

Voila un morceau de code :

Code :
  1. int largeurFen ;     // largeur en pixel de la fenetre
  2. int hauteurFen ;     // hauteur en pixel de la fenetre
  3. HBITMAP hBmpFond ;     // identifiant de l'image de fond
  4. /*---------------*/
  5. BITMAP bmfond ;   // informations su l'image de fond
  6. // charger l'image de fond
  7. hBmpFond = LoadBitmap (GetModuleHandle (NULL), MAKEINTRESOURCE (IDB_FOND)) ;
  8. if (hBmpFond == NULL)
  9. {
  10. // lever l'exception
  11. throw (logic_error ("Impossible de lire une image de fond" )) ;
  12. }
  13. // recuperer les informations sur l'image dans une structure BITMAP
  14. GetObject (hBmpFond, sizeof (bmfond), &bmfond) ;
  15. // etirer la fenetre aux dimensions de l'image
  16. largeurFen = bmfond.bmWidth ;
  17. hauteurFen = bmfond.bmHeight ;
  18. /*---------------*/
  19. HDC hDc ;    // contexte de peripherique
  20. PAINTSTRUCT ps ;  // attributs relatif a l'affichage de la fenetre
  21. HDC hDcMem ;   // contexte de peripherique memoire
  22. HBITMAP hBmpOld ;  // ancienne image du contexte
  23. // on doit afficher la fenetre
  24. case WM_PAINT :
  25. // recuperer le contexte de peripherique de la fenetre
  26. hDc = BeginPaint (hWnd, &ps) ;
  27. // creer un contexte de peripherique memoire
  28. hDcMem = CreateCompatibleDC (hDc) ;
  29. // selectionner l'image
  30. hBmpOld = (HBITMAP) SelectObject (hDcMem, hBmpFond) ;
  31. // afficher l'image de fond
  32. BitBlt (hDc, 0, 0, largeurFen, hauteurFen,
  33.   hDcMem, 0, 0, SRCCOPY) ;
  34. // remettre l'image dans le contexte
  35. SelectObject (hDcMem, hBmpOld) ;
  36. // liberer le contexte de peripherique memoire
  37. DeleteDC (hDcMem) ;
  38. // on a finit d'afficher la fenetre
  39. EndPaint (hWnd, &ps) ;
  40. return 0 ;


Ici donc j'affiche une image à partir du pixel (0,0) de la fenêtre (donc l'origine en haut à gauche), et de la largeur et de la hauteur propre de l'image...
Donc pour dessiner autre part il suffit de changer les deux premieres coordonnees (nXDest, nYDest).
Les deux suivantes sont la largeur et la hauteur de l'image à afficher (nWidth, nHeight).
Les deux dernieres permettent de dessiner l'image à partir d'une coordonnées de l'image source (utile si l'image est découpé) (nXSrc, nYSrc).


Message édité par Poireau le 18-04-2003 à 19:11:28
Reply

Marsh Posté le 18-04-2003 à 19:12:10    

OK merci ! g vu ta reponse qd j'allais effacer mon message car j'avais comris. Par contre, je voudrais utiliser ShowWindows pour afficher ou non mes image mais ca ne marche pas.
 
En fait, g changer mes rectangle qui me servait de bouton par une image qui change si on est au dessu et si on clique dessus. Seulement, pour changer l'image en fonction de la position de la souris, je fais invalidateRectangle et comme tu m'as prevenue ca l'image saute.  
 
Il y a t il alors une fonction equivalente a ShowWindows pour les images. C'est peut etre la solution de HelloWorld mais g pas compris
 
Merci

Reply

Marsh Posté le 18-04-2003 à 19:19:40    

touxe a écrit :

OK merci ! g vu ta reponse qd j'allais effacer mon message car j'avais comris. Par contre, je voudrais utiliser ShowWindows pour afficher ou non mes image mais ca ne marche pas.
 
En fait, g changer mes rectangle qui me servait de bouton par une image qui change si on est au dessu et si on clique dessus. Seulement, pour changer l'image en fonction de la position de la souris, je fais invalidateRectangle et comme tu m'as prevenue ca l'image saute.  
 
Il y a t il alors une fonction equivalente a ShowWindows pour les images. C'est peut etre la solution de HelloWorld mais g pas compris
 
Merci


ShowWindow ne fonctionne pas car ce n'est pas une fenêtre, c'est juste un dessin.
Tu peux utiliser InvalidateRect (hWnd, &rect, FALSE) avec rect qui est les coordonnées de ton images dans la fenêtre. Ici, tu peux utiliser FALSE qui ne provoque pas de scintillement. Car FALSE n'efface pas la fenêtre avant de redessiner, et comme tu redessine totalement la partie de la fenêtre ca fonctionne. TRUE sert à effacer la fenêtre avant de la redessiner, d'où un passage rapide, mais visible de l'image vers un pinceau de fond de fenêtre (HBRUSH) puis vers la nouvelle image.
La méthode que j'utilise pour afficher une image différente est d'utiliser les deux dernières coordonnées de la focntion BltBit comme j'ai dit précédemment.
C'est à dire un truc du genre, avec une image composé de deux 'sous-images' horizontales de même taille :

Code :
  1. HDC hDcMem ;  // contexte de peripherique memoire
  2. HBITMAP hBmpOld ; // anciennne image du contexte
  3. // creer le contexte de peripherique memoire compatible
  4. hDcMem = CreateCompatibleDC (hDc) ;
  5. // selectionner l'image precedemment creee
  6. hBmpOld = (HBITMAP) SelectObject (hDcMem, hBmp) ;
  7. if (imageEstSelectionne)
  8. {
  9. // afficher l'image selectionne
  10. BitBlt (hDc, 0, 0, bm.bmWidth / 2, bm.bmHeight, hDcMem,
  11.   bm.bmWidth / 2, 0, SRCCOPY) ;
  12. }
  13. else
  14. {
  15. // afficher l'image normale
  16. BitBlt (hDc, 0, 0, bm.bmWidth / 2, bm.bmHeight, hDcMem,
  17.   0, 0, SRCCOPY) ;
  18. }
  19. // selectionner l'ancien bitmap pour éviter les fuites de resources
  20. SelectObject (hDcMem, hBmpOld) ;
  21. // liberer le contexte de peripherique memoire
  22. DeleteDC (hDcMem) ;

Reply

Marsh Posté le 18-04-2003 à 19:22:41    

Merci c claire !

Reply

Marsh Posté le 18-04-2003 à 21:38:42    

est il normal que l'affchage d'image prenne autant de ressources avec 4 imgages g 130 Mo de RAM prise

Reply

Marsh Posté le 18-04-2003 à 22:57:37    

touxe a écrit :

est il normal que l'affchage d'image prenne autant de ressources avec 4 imgages g 130 Mo de RAM prise


130 Mo de RAM, c'est l'utilisation totale ?  :pt1cable:  
 
Et avant le programme il y a combien ?

Reply

Marsh Posté le 18-04-2003 à 23:13:34    

sans les image je suis a 40 Mo c enorme c ouf ca :)

Reply

Marsh Posté le 18-04-2003 à 23:16:17    

touxe a écrit :

sans les image je suis a 40 Mo c enorme c ouf ca :)


Donc, il y a une fuite de ressources...
Est ce que tu fais un DeleteObject (hBmp) ; sur toutes images dans WM_DESTROY ?

Reply

Marsh Posté le 18-04-2003 à 23:31:44    

En fait je crois qu'il faut que je reorganise totalement mon algo ;) je fais beaucoup trop de InvalidateRectangle et c ca qui bouffe toutes la memoire il est sans cesse en train de reafficher. (je suis monté a 320 Mo de RAM  :pt1cable: )
 
G effacer qq ligne ou cette fonction etais et je tombe a 4 Mo ce qui je pense est bon.
 
Faut il aussi detruire ds WM_DESTROY tous ce que g cree avec CreateWindows


Message édité par touxe le 18-04-2003 à 23:33:35
Reply

Marsh Posté le 18-04-2003 à 23:44:15    

touxe a écrit :


Faut il aussi detruire ds WM_DESTROY tous ce que g cree avec CreateWindows


Il me semble que le système envoit le message WM_DESTROY aux fenêtres enfants...

Reply

Marsh Posté le 18-04-2003 à 23:52:16    

touxe a écrit :

En fait je crois qu'il faut que je reorganise totalement mon algo ;) je fais beaucoup trop de InvalidateRectangle et c ca qui bouffe toutes la memoire il est sans cesse en train de reafficher. (je suis monté a 320 Mo de RAM  :pt1cable: )
 
G effacer qq ligne ou cette fonction etais et je tombe a 4 Mo ce qui je pense est bon.
 
Faut il aussi detruire ds WM_DESTROY tous ce que g cree avec CreateWindows


 
me sert jms de InvalidateRect(), mais d'apres les man :
"The invalidated areas accumulate in the update region until the region is processed when the next WM_PAINT message occurs or until the region is validated by using the ValidateRect or ValidateRgn function."
 
Donc si t'as moins de perte de ram quand tu vires le InvalidateRect(), ca viens ptet de la... Essayes de rajouter un DefWindowProc(hWnd, msg, wParam, lParam) tout a la fin du handler WM_PAINT.
 
sinon pour le WM_DESTROY, oui c'est mieux d'essayer de liberer un maximum le max d'objets, surtout sous des os qui avaient un peu de mal avec la mémoire (95 ou 98)
 

Reply

Marsh Posté le 18-04-2003 à 23:56:29    

merci de ta reponse !
 
tu met quoi dans msg ?
 
Sinon je viens de liberer pas mal de InvalidateRectangle et je prend les image de l'exterieur et je suis a 4,2 Mo.
 
Une autre question il faut mettre quoi comme parametre a SetBkColor(hdc, ... ) pour ecrire sur un fond transparent pour ne pas avoir de carré blanc sur mon image de fond.

Reply

Marsh Posté le 19-04-2003 à 00:06:19    

touxe a écrit :

merci de ta reponse !
 
tu met quoi dans msg ?
 
Sinon je viens de liberer pas mal de InvalidateRectangle et je prend les image de l'exterieur et je suis a 4,2 Mo.
 
Une autre question il faut mettre quoi comme parametre a SetBkColor(hdc, ... ) pour ecrire sur un fond transparent pour ne pas avoir de carré blanc sur mon image de fond.


DefWindowProc(hWnd, msg, wParam, lParam)
a les mêmes paramètres que
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
donc msg = message
 
Il y a SetBkMode (hdc, TRANSPARENT) ;

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed