/***************************************************************************
Threads for INI Copier
****************************************************************************/
#define INCL_WINDIALOGS
#define INCL_WINSTDFILE
#define INCL_DOSPROCESS
#define INCL_WINLISTBOXES
#include "global.h"
#include "resource.h"
#include <string.h>
/* macro definitions */
/* global variables */
/* La variabile FileTypes serve come parametro per la WinFileDlg */
static char *FileTypes[]=
{
"Plain Text",
"Binary Data",
"INI File",
NULL
};
/* function prototypes */
/* OpenThreadException gestisce le eccezioni del thread di apertura dei
profili */
ULONG APIENTRY OpenThreadException(PEXCEPTIONREPORTRECORD pReport,
PEXCEPTIONREGISTRATIONRECORD pReg,
PCONTEXTRECORD pContext,
PVOID );
/* CloseThreadException gestisce le eccezioni dei thread di chiusura dei
profili */
ULONG APIENTRY CloseThreadException(PEXCEPTIONREPORTRECORD pReport,
PEXCEPTIONREGISTRATIONRECORD pReg,
PCONTEXTRECORD pContext,
PVOID );
/* Presenta la finestra di richiesta di un filename */
PSZ AskFileName(HWND hWnd,PSZ fName);
/* implementation */
/* Questa funzione si occupa di richiedere il filename del profilo, lo apre
e costruisce le liste in memoria. Comunica con il thread principale con dei
messaggi da me definiti */
VOID THREADFN OpenThread(ThreadData *pThread)
{
/* Questa struttura e` necessaria per registrare il gestore delle
eccezioni del thread. E` importante che sia un variabile nello stack e
deve essere la prima. */
EXCEPTIONREGISTRATIONRECORD ExceptionReg={0,OpenThreadException};
HAB habOpenThread; /* HAB di questo thread */
HMQ hmqOpenQueue; /* Handle della coda dei messaggi del thread */
/* struttura che viene passata al thread principale quando viene aperto
un file profilo */
PrfOpen Opened;
PSZ pszFileName; /* filename */
HINI hPrf; /* handle del profilo */
HWND hList[2]; /* handle delle liste */
/* Registro il gestore delle eccezioni */
DosSetExceptionHandler(&ExceptionReg);
/* Inizializzo il PM. Attenzione che il WinInitialize() e` importante,
specialmente se si usa Merlin (Warp 4.0) */
habOpenThread=WinInitialize(0);
hmqOpenQueue=WinCreateMsgQueue(habOpenThread,0);
/* Richiedo il nome del profilo da aprire */
pszFileName=AskFileName(pThread->hWnd,pThread->fName);
/* Se pszFileName e` diverso da NULL si procede aprendo il profilo
altrimenti si segnala l'errore al thread principale */
if(pszFileName != NULL)
{
/* Comunica al thread principale il nome del file */
WinSendMsg(pThread->hWnd,WM_FILENAME,
(MPARAM)pThread->Profile,pszFileName);
/* Apre il profilo per verificare che il nome sia valido */
hPrf=PrfOpenProfile(habOpenThread,pszFileName);
if(hPrf==NULLHANDLE)
{
/* Il nome non era valido e quindi mostra l'errore */
ErrorBox(IDE_CANTOPEN,FALSE);
/* Comunica l'errore al thread principale */
WinSendMsg(pThread->hWnd,WM_FILENAME,
(MPARAM)FAILURE,(MPARAM)pThread->Profile);
}
else
{
/* riempie la struttura Opened e costruisce le liste in memoria */
Opened.hWnd=pThread->hWnd;
Opened.Profile=pThread->Profile;
Opened.List=BuildLists(hPrf);
/* Ottiene gli handle delle listBox in base al profilo */
switch(pThread->Profile)
{
case PROFILE_A:
WinMultWindowFromIDs(pThread->hWnd,hList,
LIST_A,SUBLIST_A);
break;
case PROFILE_B:
WinMultWindowFromIDs(pThread->hWnd,hList,
LIST_B,SUBLIST_B);
break;
}
/* Comunica al thread principale l'avvenuta apertura */
WinSendMsg(pThread->hWnd,WM_PROFILE,
(MPARAM)pThread->Profile,&Opened);
/* Riempie le list box e chiude il profilo */
FillLists(hList[0],hList[1],Opened.List);
PrfCloseProfile(hPrf);
}
}
else /* Mando un mex per dire che non e` stato selezionato il file */
WinSendMsg(pThread->hWnd,WM_FILENAME,
(MPARAM)FAILURE,(MPARAM)pThread->Profile);
/* Distrugge le risorse PM (Queue & Anchor Block) */
WinDestroyMsgQueue(hmqOpenQueue);
WinTerminate(habOpenThread);
MemFree(pThread); /* Libera la struttura passata al Thread */
/* rimuove il gestore delle eccezioni */
DosUnsetExceptionHandler(&ExceptionReg);
}
/* Chiede il nome del file da aprire */
PSZ AskFileName(HWND hWnd,PSZ fName)
{
FILEDLG DlgData; /* struttura per la file dialog */
HWND hFileDlg; /* Handle della dialog */
PSZ pszName; /* FileName */
memset(&DlgData,0,sizeof(FILEDLG)); /* azzera la struttura */
/* Riempie la struttura */
DlgData.cbSize=sizeof(FILEDLG);
DlgData.fl=FDS_OPEN_DIALOG;
DlgData.pszIType=NULL; /* Filtro sugli extended attributes */
DlgData.papszITypeList=(PAPSZ)FileTypes; /* Lista dei tipi da selezionare */
/* Se viene passato un filename si estrae la path */
if(fName!=NULL)
{
pszName=strrchr(fName,'\\'); /* Cerca la slash */
if(pszName==NULL)
pszName=strrchr(fName,':'); /* se non la trova cerca i due punti */
if(pszName!=NULL) /* se ha trovato una path la copia */
strncpy(DlgData.szFullFile,fName,pszName-fName+1);
}
strcat(DlgData.szFullFile,"*.INI"); /* aggiunge il filtro sull'estensione */
/* Crea la dialog */
hFileDlg=WinFileDlg(HWND_DESKTOP,NULLHANDLE,&DlgData);
/* Se e` stato correttamente selezionato un file */
if(hFileDlg && (DlgData.lReturn==DID_OK))
{
/* Restituisce una copia del filename */
pszName=(PSZ)Memory(strlen(DlgData.szFullFile)+1);
strcpy(pszName,DlgData.szFullFile);
return pszName;
}
/* Non e` stato selezionato alcun file */
return NULL;
}
/* Questa funzione si occupa di rimuovere tutte le strutture in memoria
legate ad un profilo */
VOID THREADFN CloseThread(PrfOpen *pPrfData)
{
/* Struttura per registrare il gestore delle eccezioni */
EXCEPTIONREGISTRATIONRECORD ExceptionReg={0,CloseThreadException};
HAB habCloseThread; /* handle dell'anchor block */
HMQ hmqCloseQueue; /* handle della message queue */
HWND hList[2]; /* Handle delle list box */
/* Registra il gestore delle eccezioni */
DosSetExceptionHandler(&ExceptionReg);
/* Inizializza il PM e crea la coda dei messaggi */
habCloseThread=WinInitialize(0);
hmqCloseQueue=WinCreateMsgQueue(habCloseThread,0);
/* distrugge le liste */
ClearLists(pPrfData->List);
/* Ottiene gli handle delle listBox giuste */
switch(pPrfData->Profile)
{
case PROFILE_A:
WinMultWindowFromIDs(pPrfData->hWnd,hList,
LIST_A,SUBLIST_A);
break;
case PROFILE_B:
WinMultWindowFromIDs(pPrfData->hWnd,hList,
LIST_B,SUBLIST_B);
break;
}
/* Cancella il contenuto delle liste */
WinSendMsg(hList[0],LM_DELETEALL,NULL,NULL);
WinSendMsg(hList[1],LM_DELETEALL,NULL,NULL);
/* comunica al thread principale che il profilo e` stato chiuso
correttamente */
WinSendMsg(pPrfData->hWnd,WM_PROFILECLOSED,
(MPARAM)pPrfData->Profile,(MPARAM)pPrfData);
/* Distrugge la coda dei messaggi */
WinDestroyMsgQueue(hmqCloseQueue);
WinTerminate(habCloseThread);
/* Libera la memoria della struttura pPrfData e rimuove il gestore delle
eccezioni */
MemFree(pPrfData);
DosUnsetExceptionHandler(&ExceptionReg);
}
/* Gestore delle eccezioni del thread di apertura del profilo */
ULONG APIENTRY OpenThreadException(PEXCEPTIONREPORTRECORD pReport,
PEXCEPTIONREGISTRATIONRECORD pReg,
PCONTEXTRECORD pContext,
PVOID pDispatcher)
{
switch(pReport->ExceptionNum)
{
/* Il thread e` stato interrotto da un altro processo quindi
avverte il thread principale */
case XCPT_ASYNC_PROCESS_TERMINATE:
WinSendMsg(hMainWindow,WM_PROFILE,(MPARAM)FAILURE,
(MPARAM)(pReport->ExceptionNum));
_endthread();
break;
/* E` avvenuto un errore quindi si avverte il thread principale
e si mostrano i dati dell'eccezione */
case XCPT_ACCESS_VIOLATION:
WinSendMsg(hMainWindow,WM_PROFILE,(MPARAM)FAILURE,
(MPARAM)(pReport->ExceptionNum));
ExcptBox(pReport);
break;
default:
break;
}
return XCPT_CONTINUE_SEARCH;
}
/* gestisce le eccezioni del thread di chiusura */
ULONG APIENTRY CloseThreadException(PEXCEPTIONREPORTRECORD pReport,
PEXCEPTIONREGISTRATIONRECORD pReg,
PCONTEXTRECORD pContext,
PVOID pDispatcher)
{
switch(pReport->ExceptionNum)
{
case XCPT_ASYNC_PROCESS_TERMINATE:
_endthread();
break;
/* Mostra un messaggio d'errore */
case XCPT_ACCESS_VIOLATION:
ErrorBox(IDE_CLOSEXCP,TRUE);
break;
default:
break;
}
return XCPT_CONTINUE_SEARCH;
}
Last modified 27-10-97 |