ncoder
Messages postés244Date d'inscriptionvendredi 6 mai 2005StatutMembreDernière intervention 6 avril 2008
-
30 nov. 2005 à 17:30
ncoder
Messages postés244Date d'inscriptionvendredi 6 mai 2005StatutMembreDernière intervention 6 avril 2008
-
11 déc. 2005 à 13:48
Bonjour à tous,
Dans beaucoup de mes programmes, lorsqu'une opération assez longue est en cours, j'utilise une petite fenètre indicant l'état et la tache en cours d'exécution.
Fatigué d'avoir à chaque fois a retaper les lignes de code pour cette petite fenètre, j'ai voulu mettre tout ce code dans une DLL, en faisant 3 fonctions:
- une pour créer la fenètre (initialiser)
- une pour changer le texte de l'opération en cours
- et une pour changer la valeur de la progressbar.
BOOL APIENTRY DllMain (HINSTANCE hInst /* Library instance handle. */ ,
DWORD reason /* Reason this function is being called. */ ,
LPVOID reserved /* Not used. */ )
{
switch (reason)
{
case DLL_PROCESS_ATTACH:
break;
case DLL_PROCESS_DETACH:
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
}
/* Returns TRUE on success, FALSE on failure */
return TRUE;
}
Dev Cpp ne me génère aucune erreur, me crée la lib et la DLL.
Mais qd j'utilise ma DLL, les MsgBox s'affichent bien (donc les fonctions sont appelées),
mais ma fenètre n'apparait pas !!!
cs_Xaviou
Messages postés154Date d'inscriptiondimanche 1 avril 2001StatutMembreDernière intervention 2 octobre 2009 5 déc. 2005 à 18:11
Essayes avec ça:
Dans ta DLL:
DWORD thID;
DWORD WINAPI ThreadFunction(LPVOID lPar)
{
WNDCLASSEX wcex;
wcex.hInstance=GetModuleHandle(NULL);
wcex.lpfnWndProc= Nom d'une fonction WndProc dans la Dll pour gérer la fenêtre
wcex.lpszClassName="DbgWnd_Class";
....
RegisterClassEx(&wcex);
HWND hWnd=CreateWindow(
"DbgWnd_Class","Messages...",WS_VISIBLE,
CW_USEDEFAULT,0,400,200,HWND_DESKTOP,NULL,GetModuleHandle(NULL),0);
// Ajoutes tes contrôles ici...
ShowWindow(hWnd,SW_SHOW);
UpdateWindow(hWnd);
// On met ensuite une pompe à messages
MSG msg;
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
if (FlgStop==true) // FlgStop est un booléen qui te permettra de stopper le thread
{
FlgStop=false;
DestroyWindow(hWnd);
}
}
return 0; // renvoie ce que tu veux...
}
extern "C" __declspec(dllexport) int CreateDebugWindow()
{
hThread=CreateThread(NULL,0,MainFuntion,NULL,0,&thID);
// Vérifies si tout c'est bien passé
return 1;
}
extern "C" __declspec(dllexport) int StopDebugWindow()
{
FlgStop=true;
// On boucle jusqu'à ce que la variable FlgStop ait été remise à false
// par la pompe à messages de ThreadFunction
while(
FlgStop
);
return 1;
}
// Tu peux ajouter une fonction exportée pour afficher des messages dans ta fenêtres
Puis, dans ton Prog, tu ajoutes ceci pour créer ta fenêtre:
typedef int (WINAPI *CREATE_FUNCTION)(void);
HMODULE Handle=LoadLibrary(MaDll.dll");
if (Handle==NULL) => Erreur
CREATE_FUNCTION MyCreateFunction=GetProcAddress(Handle,"CreateDebugWindow");
if (MyCreateFunction==NULL) => Erreur
// Créer la fenêtre
MyCreateFunction();
Je t'ai fais quelque-chose de sommaire, à toi de mettre les vérifications nécessaires.
Bonne chance.
cs_Xaviou
Messages postés154Date d'inscriptiondimanche 1 avril 2001StatutMembreDernière intervention 2 octobre 2009 9 déc. 2005 à 22:35
C'est quand même bizzare que la 1ère ne marche pas.
Fais attention, car dans l'exemple que je t'ai filé, il y a un petit problème.
Je m'explique :
La fonction CreateMsgWindow crée le thread servant à la gestion de la fenêtre, et retourne la valeur 1 si tout est OK.
Le problème, c'est que quand elle redonne la main, la fenêtre n'est pas encore créée. Ton problème avec SetWindowText() vient peut-être de là...
J'ai résolu ce problème en faisant de la façon suivante: (les parties modifiées apparaissent en violet)
DLLIMPORT int CreateMsgWindow(HWND hParent)
{
if (FlgCreated==true) return 0;
hPrntWnd=hPrntWnd;
InitCommonControls();
hModule=GetModuleHandle(NULL);
hEvent=CreateEvent(NULL,FALSE,FALSE,NULL);
hThread=CreateThread(NULL,0,ThreadFunction,hEvent,0,&thID);
// On attend maximum 15 secondes que le thread ait créé la fenêtre
DWORD dwRes=WaitForSingleObject(hEvent,15000);
CloseHandle(hEvent);
if (dwRes==WAIT_TIMEOUT) // Si les 15 secondes d'attente sont passées
return 0;
return 1;
}
Puis, dans la ThreadFunction :
DWORD WINAPI ThreadFunction(LPVOID lPar)
{
WNDCLASS wc;
wc.cbClsExtra=0;
wc.cbWndExtra=0;
wc.hbrBackground=(HBRUSH)(COLOR_BTNFACE+1);
wc.hCursor=LoadCursor(NULL,IDC_ARROW);
wc.hIcon=LoadIcon(NULL,IDI_APPLICATION);
wc.hInstance=GetModuleHandle(NULL);
wc.lpfnWndProc=MainWndProc;
wc.lpszClassName="Msg_Wnd_Class";
wc.lpszMenuName=NULL;
wc.style=CS_HREDRAW|CS_VREDRAW;
RegisterClass(&wc);
// Création de la fenêtre principale
hWndMain=CreateWindowEx(WS_EX_TOPMOST|WS_EX_TOOLWINDOW,"Msg_Wnd_Class","Messages",WS_THICKFRAME|WS_VISIBLE,CW_USEDEFAULT,0,350,150,hPrntWnd,NULL,GetModuleHandle(NULL),0);
// Création de la TextBox
hTxtMsg=CreateWindowEx(WS_EX_CLIENTEDGE,"EDIT","",WS_VISIBLE|WS_CHILD|WS_HSCROLL|WS_VSCROLL|ES_MULTILINE|ES_AUTOHSCROLL|ES_AUTOVSCROLL,5,5,10,10,hWndMain,NULL,GetModuleHandle(NULL),0);
ShowWindow(hWndMain,SW_SHOW);
UpdateWindow(hWndMain);
FlgCreated=true;
// Tout s'est bien passé, on peut libérer la fonction create qui attend
SetEvent((HANDLE)lPar);
// On met une pompe à messages pour que ça tourne correctement
MSG msg;
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}