Team OS/2 Italia - Developer Assistant

------------------------------------------

INI Copier v1.00

Un esempio di programma PM Multi-Threaded

main.c


/***************************************************************************
 
 Main program for INI Copier
 
 In questo modulo risiede la funzione principale del programma.
 
 ****************************************************************************/

#define INCL_DOSSEMAPHORES
#define INCL_DOSERRORS

#include "global.h"
#include "resource.h"
#include <stdlib.h>

/* global variables */

/* Tutte le variabili globali vengono inizializzate */
HAB     habMainThread=NULLHANDLE;
HMQ     hmqMessageQueue=NULLHANDLE;
PSZ     pszClassName=NULL;          /* Nome della classe della finestra
                                       principale */
PSZ     pszAppTitle=NULL;           /* Nome dell'applicazione */
HWND    hMainWindow=NULLHANDLE;     /* handle della finestra principale */

/* function prototypes */

int Initialize(void);  /* inizializza il programma */
void Terminate(void);  /* libera tutte le risorse */

/* MainException gestisce le eccezioni del thread principale */
ULONG APIENTRY MainException(PEXCEPTIONREPORTRECORD pReport,
                             PEXCEPTIONREGISTRATIONRECORD pReg,
                             PCONTEXTRECORD pContext,
                             PVOID );

/* implementation */

void main(int argc,char **argv)
{
    EXCEPTIONREGISTRATIONRECORD ExceptionReg={0,MainException};
    QMSG    qmsg;
    APIRET  rc;

/* registro il mio gestore delle eccezioni */
    DosSetExceptionHandler(&ExceptionReg);

/* inizializzo il PM per questo thread in caso di insuccesso termino il
   programma */
    habMainThread=WinInitialize(0);
    if(habMainThread==NULLHANDLE)
        exit(-1);

/* Metto Terminate() nella lista delle funzioni da chiamare all'uscita */
    atexit(Terminate);

/* Inizializzo e in caso di insuccesso mostro il messaggio d'errore e
   termino il programma */
    if(Initialize()==FALSE)
        ErrorBox(IDE_INITIALIZE,TRUE);
    
/* Loop principale di gestione dei messaggi */
    while(WinGetMsg(habMainThread,&qmsg,NULLHANDLE,(ULONG)NULL,(ULONG)NULL))
        WinDispatchMsg(habMainThread,&qmsg);

/* Rimuovo il mio gestore delle eccezioni */
    DosUnsetExceptionHandler(&ExceptionReg);
}


/* Inizializzazione del programma */
int Initialize(void)
{
    BOOL    rc;
    PFNWP   pOldFrameProc;
    
/* Creo la coda dei messaggi per questo thread, in caso di insuccesso
   mostro un messaggio d'errore e termino il programma */
    hmqMessageQueue=WinCreateMsgQueue(habMainThread,0);
    if(hmqMessageQueue==NULLHANDLE)
        ErrorBox(IDE_MSGQUEUE,TRUE);

/* Leggo dalle risorse il nome della classe della finestra principale e
   registro la classe, controlla che la classe sia registrata  */
    pszClassName=LoadString(IDS_WNDCLASS);
    rc=WinRegisterClass(habMainThread,pszClassName,
                        MainWndProc,0,sizeof(void *));
    if(rc==FALSE)
        ErrorBox(IDE_WNDCLSREG,TRUE);

/* Leggo dalle risorse il nome del programma e creo la finestra principale
   a partire dalle risorse. I messaggi inviati dalla WinLoadDlg vengono
   gestiti dalla WinDefDlgProc. Controllo he la finestra sia creata */
    pszAppTitle=LoadString(IDS_APPNAME);
    hMainWindow=WinLoadDlg(HWND_DESKTOP,HWND_DESKTOP,
                           WinDefDlgProc,
                           NULLHANDLE, WIN_INICOPIER,
                           NULL);
    if(hMainWindow==NULLHANDLE)
        ErrorBox(IDE_MAINWND,TRUE);
    
/* Faccio il subclssing del Frame della finestra principale in modo da poter
   controllare il resizing */
    pOldFrameProc=WinSubclassWindow(hMainWindow,(PFNWP)SubFrameProc);
    if(pOldFrameProc == NULL)
        ErrorBox(IDE_MAINWND,TRUE);

/* Salvo tra i dati della finestra l'indirizzo della procedura del Frame */
    WinSetWindowULong(hMainWindow,QWL_USER,(ULONG)pOldFrameProc);

/* Aggiorno il nome dell'applicazione e mi assicuro che la finestra sia
   visibile */
    WinSetWindowText(hMainWindow,pszAppTitle);
    WinShowWindow(hMainWindow,TRUE);
    
    return TRUE;
}

/* Terminate() si occupa di liberare tutte le risorse richieste, viene 
   chiamata a seguito din un exit() o a conclusione della Main() */
void Terminate(void)
{
/* Se PM non e` stato inizializzato non c'e` niente da fare ed esce subito */
    if(habMainThread==NULLHANDLE)
        return;

/* Distrugge la finestra principale, la coda dei messaggi */
    if(hMainWindow!=NULLHANDLE)
        WinDestroyWindow(hMainWindow);
    if(hmqMessageQueue!=NULLHANDLE)
        WinDestroyMsgQueue(hmqMessageQueue);

/* Libera alcune zone di memoria */
    MemFree(pszClassName);
    MemFree(pszAppTitle);
    
/* termina il pM per questo thread */
    WinTerminate(habMainThread);
}

/* Libera zone di memoria allocate con Memory, gestisce i puntatori NULL */
void MemFree(void *pv)
{
/* Se pv non e` NULL libera il blocco di memoria */
    if(pv!=NULL)
    {
    	free(pv);
    }
}

/* richiede un blocco di memoria di dimesione size, gestendo gli errori */ 
void *Memory(int size)
{
    void    *vpMem;
    
    vpMem=malloc(size);

/* Se malloc non ha trovato memoria mostra un messaggio d'errore e
   termina il programma */
    if(vpMem==NULL)
        ErrorBox(IDE_MEMORY,TRUE);
    return vpMem;
}

/* Gestore delle eccezioni */
ULONG APIENTRY MainException(PEXCEPTIONREPORTRECORD pReport,
                             PEXCEPTIONREGISTRATIONRECORD pReg,
                             PCONTEXTRECORD pContext,
                             PVOID pDispatcher)
{
    switch(pReport->ExceptionNum)
    {

/* Se c'e` una violazione d'accesso alla memoria e il PM e` inizializzato
   mostra le informazioni sull'eccezione */
        case XCPT_ACCESS_VIOLATION:
            if(habMainThread!=NULLHANDLE)
            	ExcptBox(pReport);
            break;
        default:
            break;
    }

/* Passa l'ecezione al gestore successivo (cioe` quello di sistema) */
    return XCPT_CONTINUE_SEARCH;
}

/* fine di main.c */

---------------------------------------------------

Torna alla nostra HomePage - Pagina a cura di: Giovanni Pagni
Last modified 24-11-97