Visualizzazione dei risultati da 1 a 7 su 7
  1. #1
    Utente di HTML.it
    Registrato dal
    Mar 2007
    Messaggi
    151

    [c++] Windows API: oggetto HDC

    Salve a tutti.
    Sto creando un programma in C++ che utilizza le librerie grafiche WxWidgets.
    Ho trovato una libreria che implementa alcune funzioni che mi servono all'interno del mio programma. Tra queste funzioni, ce n'è una che richiede come argomento un oggetto di tipo HDC che credo sia un oggetto definito nelle Windows API, per disegnare un'immagine. Ecco la funzione:
    codice:
    void DrawBarcode(HDC hDC,int iX,int iY0,int iY10,int iY11,const COLORREF clrBar,const COLORREF clrSpace,const int iPenW)
    Io sto utilizzando le librerie grafiche WxWidgets, ho creato un frame ed ho visto che esiste la funzione:
    codice:
    wxWindow::GetHandle
    void* GetHandle() const
    /*
    Returns the platform-specific handle of the physical window.
    Cast it to an appropriate handle, such as HWND for Windows, Widget for Motif, GtkWidget for GTK or WinHandle for PalmOS.
    */
    Ho provato a fare una così:

    codice:
    HWND hwnd = (HWND) frame->GetHandle();
    Ora, le mie domande sono queste:
    1) E' corretto questo cast:
    HWND hwnd = (HWND) frame->GetHandle();
    tenendo conto che GetHandle ha questo prototipo:
    void* GetHandle() const

    2) Come uso l'oggetto di tipo HWND? E' possibile ottenere da questo un oggetto HDC?

    Grazie mille, saluti

  2. #2
    Ciao,

    si, è possibile ottenere un handle al device context, così:

    codice:
    HDC hdc = GetDC(hwnd); // ottengo l'handle al device context
    ... // utilizzo l'handle per disegnare
    ReleaseDC(hwnd, hdc);  // lo rilascio quando non mi serve più
    Si utilizza la funzione API GetDC per ottenere l'handle al device context a partire da quello della finestra. Alla fine bisogna rilasciare l'HDC con la funzione API ReleaseDC.

  3. #3
    Utente di HTML.it
    Registrato dal
    Mar 2007
    Messaggi
    151
    Ok, grazie mille per la risposta.
    Forse sono riuscito a disegnare. Dico forse perchè in realtà non vedo niente e non capisco se ciò sia dovuto:
    1) al pannello che sta all'interno del Frame o
    2) perchè ho dato le coordinate sbagliate.

    Esiste un modo per ottenere le coordinate che posso passare alla funzione LineTo?
    Grazie mille.
    Saluti

  4. #4
    Originariamente inviato da senise
    Ok, grazie mille per la risposta.
    Forse sono riuscito a disegnare. Dico forse perchè in realtà non vedo niente e non capisco se ciò sia dovuto:
    1) al pannello che sta all'interno del Frame o
    2) perchè ho dato le coordinate sbagliate.

    Esiste un modo per ottenere le coordinate che posso passare alla funzione LineTo?
    Grazie mille.
    Saluti
    Ciao Senise,

    non so se ti riferisci alla libreria wxWidgets o alla API.
    Nel primo caso non posso aiutarti(ché non me ne intendo). Se vuoi posso spiegarti come utilizzare le funzioni per il disegno nella Win API con un piccolo programma di esempio.

  5. #5
    Utente di HTML.it
    Registrato dal
    Mar 2007
    Messaggi
    151
    No, io mi riferivo alle WINAPI!
    Devo disegnare con quelle,in particolare con il metodo "LineTo" però il FRAME è stato creato con le WxWidgets da cui ho ricavato, tramite un'apposita funzione, l'oggetto HWND e poi con il metodo da te suggerito quello HDC.
    Se saresti così gentile da farmi vedere un esempio, te ne sarei molto grato, dato che non ho mai usato le WinAPI e non mi sembrano abbastanza amichevoli.
    Grazie!
    Saluti

  6. #6
    Il programma seguente disegna una linea orizzontale che divide la finestra in due. Un po' al di sopra della linea, stampa la stringa "Ciao, Mondo":



    codice:
    #include <windows.h>
    
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    
    int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                        PSTR szCmdLine, int iCmdShow)
    {
         static TCHAR szAppName[] = TEXT("CiaoMondo");
         HWND         hwnd;
         MSG          msg;
         WNDCLASS     wndclass;
    
         wndclass.style         = CS_HREDRAW | CS_VREDRAW;
         wndclass.lpfnWndProc   = WndProc;
         wndclass.cbClsExtra    = 0;
         wndclass.cbWndExtra    = 0;
         wndclass.hInstance     = hInstance;
         wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION);
         wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW);
         wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
         wndclass.lpszMenuName  = NULL;
         wndclass.lpszClassName = szAppName;
    
         if (!RegisterClass (&wndclass))
         {
              MessageBox (NULL,
    		TEXT ("Errore nella registrazione della classe di finestra!"), 
                          szAppName,
    		MB_ICONERROR);
              return 0;
         }
         
         hwnd = CreateWindow(szAppName,           // Nome della window class
    		TEXT ("Il titolo"),  // Stringa che appare sulla barra del titolo
                             WS_OVERLAPPEDWINDOW, // Stile window
                             CW_USEDEFAULT,       // Questo e i successivi
                             CW_USEDEFAULT,       // tre parametri definiscono
                             CW_USEDEFAULT,       // la posizione iniziale
                             CW_USEDEFAULT,       // della finestra.
                             NULL,                // Handle alla finestra padre
                             NULL,                // Handle al menu della finestra
                             hInstance,           // Handle all'istanza del programma
                             NULL);               // Parametri di creazione della finestra
         
         ShowWindow(hwnd, iCmdShow);
         UpdateWindow(hwnd);
         
         while (GetMessage(&msg, NULL, 0, 0))
         {
              TranslateMessage(&msg) ;
              DispatchMessage(&msg) ;
         }
    
         return msg.wParam;
    }
    
    LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
         HDC         hdc;
         PAINTSTRUCT ps;
         RECT        rect;
    	 static int  cxClient, cyClient;
         
         switch (message)
         {
         case WM_CREATE:
              return 0;
    
    	 case WM_SIZE:
              cxClient = LOWORD (lParam) ;
              cyClient = HIWORD (lParam) ;
              return 0 ;
              
         case WM_PAINT:
              hdc = BeginPaint (hwnd, &ps);
              
              GetClientRect (hwnd, &rect);
    
    		  rect.top -= 20;
              
              DrawText (hdc, TEXT ("Ciao, Mondo!"), -1, &rect,
                        DT_SINGLELINE | DT_CENTER | DT_VCENTER);
    
    		  MoveToEx (hdc, 0,        cyClient / 2, NULL) ;
              LineTo   (hdc, cxClient, cyClient / 2) ;
    
              
              EndPaint (hwnd, &ps);
              return 0;
              
         case WM_DESTROY:
              PostQuitMessage (0);
              return 0;
         }
    
         return DefWindowProc (hwnd, message, wParam, lParam);
    }
    Come vedi, un programma winapi ha il suo punto di ingresso nella funzione WinMain(al contrario dei programmi console che hanno il punto di ingresso nella funzione main).
    Nella WinMain si definisce una struttura WNDCLASS e si impostano i vari campi(fra i quali, importantissimo, il campo lpfnWndProc che è un puntatore alla Window Procedure).
    La Window Procedure è la funzione che si occupa di gestire i messaggi che Windows invia al programma, come la creazione della finestra o, ed è il caso che più ci interessa, il messaggio WM_PAINT che serve per disegnare nella client area della finestra.
    Successivamente vengono chiamate quattro funzioni:

    RegisterClass
    CreateWindow
    ShowWindow
    UpdateWindow

    Il cui compito è bene illustrato dal loro nome(se qualcosa non ti è chiaro, chiedi pure).

    Nella WinMain, infine, viene avviato il loop dei messaggi che consente al sistema operativo di inviare i messaggi alla nostra finestra/applicazione:

    codice:
    ...
         while (GetMessage(&msg, NULL, 0, 0))
         {
              TranslateMessage(&msg) ;
              DispatchMessage(&msg) ;
         }
    ...
    Nella Window Procedure:

    codice:
    LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    Scriviamo il codice per la gestione dei messaggi che ci interessano(nel nostro caso siamo particolarmente interessati al messaggio WM_PAINT).
    Come vedi, per ottenere un HDC all'interno del messaggio WM_PAINT non si usa la funzione GetDC ma BeginPaint. Per rilasciare l'HDC al termine delle operazioni di disegno, si utilizza invece la funzione EndPaint.
    GetDC e ReleaseDC si utilizzano invece se si vuole ottenere un HDC all'esterno del messaggio WM_PAINT.

    Per disegnare il testo si utilizza la funzione DrawText(ma ne esistono, nella API, anche altre con svariati compiti/finalità).
    Per disegnare la linea, il codice è il seguente:

    codice:
    ...
    MoveToEx (hdc, 0, cyClient / 2, NULL) ;
    LineTo   (hdc, cxClient, cyClient / 2) ;
    ...
    Le coordinate dell'area client delle finestra, cyClient e cxClient, vanno prese durante l'eleborazione del messaggio WM_SIZE in modo che vengano aggiornate quando l'utente ridimensiona la finestra.



    P.S.
    Ripeto, chiedi pure in caso di dubbi.

  7. #7
    Utente di HTML.it
    Registrato dal
    Mar 2007
    Messaggi
    151
    Vincenzo1968 grazie mille per l'esempio, che mi ha fatto capire che forse la strada che sto percorrendo è ripida e tortuosa. L'esempio è molto chiaro, ma credo sia molto difficile utilizzare le WinAPI dalle WxWidgets. Dalle prove che ho fatto, non ho accesso alla struttura WNDCLASS e non saprei come cambiare il ciclo dei messaggi. L'unico oggetto che ho a disposizione è l'handle ad HWND.
    Forse a questo punto è meglio cercare un'altra libraria che si interfacci nativamente con le WxWidgets piuttosto che con le WinApi.
    Ti ringrazio ancora.
    Saluti

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.