Newsgroup: it.comp.lang.c++
Titolo: Struttura programma win32 con windows child

Ho un problema che a molti di voi sembrerà banale ma purtroppo con la mia
scarsa esperienza in ambiente win32 non riesco a venirne fuori.....
Ho una applicazione la cui finestra principale e' una dialog. Nella WinMain
tutto si risolve con una semplice DialogBox(...), e fin qui tutto funziona.
Ora e' nata l'esigenza di avere due aree (all'interno della dialog
principale) in cui devo disegnare velocemente dei grafici ed altre cose in
modo "asincrono" rispetto gli eventi della dialog (in pratica il contenuto
delle due finestre verrà continuamente ridisegnato). Pensavo di creare due
window dichiarandole CHILD della dialog principale....e qui tutto mi si
incasina!! Dove metto il ciclo dei messaggi? Dove dichiaro la classe della
finstra?? I messaggi WM_PAINT arriveranno alle funzioni delle finestre child
o alla dialog ?? Devo autilizzare DialogBox(..), CreateDialog(...) o
cos'altro?? Ho provato 1000 strade e qualche cosa alla fine sembra
funzionare ma la struttura e' incasinatissima....sicuramente esiste una
strada più lineare ed elegante!! Un'ultima cosa....anche se il resto del
codice utilizza C++ per quanto riguarda l'ossatura dell'applicazione
preferirei utilizzare direttamente le API quindi niente OWL o MFC!
Grazie fin d'ora a chi mi indicherà la strada giusta.....
Ciao Andrea
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
per rispndere rimuovere NOSPAM dall'indirizzo
to reply please remove NOSPAM from the address
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
** La nuvoletta del Ragioniere e' ben poca cosa se confrontata con
l'anticiclone del Programmatore! **

preferirei utilizzare direttamente le API quindi niente OWL o MFC!
Allora, API nude, niente framework, non stupirti se la struttura
e` non poco incasinata, comunque un esempiucolo giocattolo
potrebbe essere cosi`...:
#define STRICT
#include <windows.h>
// dichiarazione forward della window procedure
LRESULT CALLBACK WindowProc(HWND hWnd, UINT wMsg, WPARAM
    wParam, LONG lParam);
// dichiarazione forward della dialog procedure
BOOL CALLBACK DlgProc(HWND hwndDlg, UINT uMsg, WPARAM
    wParam, LPARAM lParam);
// l'entry point di qualsiasi programma Windows:
int WINAPI
WinMain(HINSTANCE hInstance, HINSTANCE hPrev,
    LPSTR lpCmdline, int nShow)
{
    // 1. defiamo la classe
    WNDCLASS wndClass;
    ZeroMemory(&wndClass, sizeof(wndClass));
    wndClass.hInstance     = hInstance;
    wndClass.lpfnWndProc   = WindowProc;
    wndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wndClass.lpszClassName = "Esempio";
    if(!RegisterClass(&wndClass))
        return FALSE;
    // 2. attiviamo il dialogo (modale)
    int rc = DialogBox(hInstance, "Id_Dialogo", 0, DlgProc);
    // 3. mostriamo il risultato (tasto premuto per chiudere)
    char buf[80];
    wsprintf(buf,"Risult=%d",rc);
    MessageBox(0, buf,"Fatto!",MB_OK);
    return 0;
}
BOOL CALLBACK
DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch(uMsg) {
    // 2.1: inizializziamo il dialogo
    case WM_INITDIALOG: {
        // 2.2: creiamo una finestra-figlio
        HWND mywin = CreateWindow("Esempio", "Finestra d'esempio",
            WS_VISIBLE | WS_CHILD,  // gli stili
            10, 10, 100, 100,                     // le coordinate
            hwndDlg, (HMENU)101, GetModuleHandle(0), 0);
        // 2.3: aggiungiamo un timer alla finestra
        //      (msg WM_TIMER ogni secondo circa)
        SetTimer(mywin, 1, 1000, 0);
        // 2.4: inizializziamo il campo-dati
        SetWindowLong(mywin,GWL_USERDATA,0);
                        }
        return FALSE;
    // 2.9: premuto un bottone
    case WM_COMMAND:
        return EndDialog(hwndDlg,LOWORD(wParam));
    }
    return 0;
}
LRESULT CALLBACK
WindowProc(HWND hWnd, UINT wMsg, WPARAM wParam, LONG lParam)
{
    switch(wMsg)
    {
    case WM_TIMER: {
        // 2.5: e` scoccato un secondo...!
        LONG ld = GetWindowLong(hWnd,GWL_USERDATA);
        SetWindowLong(hWnd,GWL_USERDATA,ld+1);
        InvalidateRect(hWnd,0,TRUE);
        UpdateWindow(hWnd);
                   }
    case WM_PAINT: {
        // 2.6: spesso causato dal WM_TIMER
        HDC         hDC;
        PAINTSTRUCT ps;
        if(hDC = BeginPaint(hWnd, &ps)) {
            LONG ld = GetWindowLong(hWnd,GWL_USERDATA);
            char buff[20];
            wsprintf(buff,"%d",ld);
            TextOut(hDC, 10, 60, buff, lstrlen(buff));
            EndPaint(hWnd, &ps);
        }
                   }
        break;
    default:
        return DefWindowProc(hWnd, wMsg, wParam, lParam);
    }
    return FALSE;
}
I numeri dei commenti indicano un "tipico ordine di svolgimento",
ovvero, "ordine in cui spesso succedono le cose".  Un programma
"ad eventi", e cosi` sono quelli Windows, non e` "deterministico
top-down" nel senso in cui siamo abituati a vedere i programmi
che a eventi non sono... comunque, certe tipiche "sequenze" di
occorrenze sono abbastanza predicibili.
Alex

 cos'altro?? 
Se una dialog modale ti basta (come credo sia il caso):
usa DialogBox() e vai col tango
Se ti serve una finestra modeless:
Carica la la dialog dalle risorse con CreateDialog() e poi mostrala con 
ShowWindow(). Subito dopo pero' devi mettere un message loop, altrimenti 
esci dalla WinMain e il programma termina...
Ricorda poi che se la dialog box non e' modale non deve distruggersi con 
EndDialog() ma con DestroyWindow() (bleah...semplicemente rivoltante... ;) 
Ciao,
Antonello
-- 
// --------------------------------------------------------
// Antonello Salvatucci, Software Engineer
// LEGO Media International
// Klovermarken 120, 7190 Billund DENMARK
//
// antonello at digi. lego. com         
http://www.lego.com

Se usi DialogBox() il ciclo dei messaggi e' inserito al suo interno.
Se vuoi fare un tuo ciclo dei messaggi devi usare CreateDialog().
In alternativa puoi creare un thread con un secondo ciclo dei messaggi che
si occupi delle altre 2 finestre.
Ciao.
--
Antonio Donatiello

Grazie 1000 a tutti per le "dritte"
