Multithreading avec TMessage
Bonjour à tous,
Suite au sujet Utilisation de RawInput, un nouveau problème m'est apparu : Le ressources utilisées par le traitement.
Je m'explique, dans ma solution de RawInput, ma fonction WMInput vers laquelle sont redirigés tout les messages WM_INPUT tourne donc constamment pour effectuer le traitement lié à mes données de souris.
Le problème, c'est qu'une fois le traitement activé, je ne peux plus rien faire, l'application est comme "figée" bien que les valeurs indiquées dans mon TEdit se mettent bien à jour.
J'ai donc fait quelques recherches sur les Threads, j'ai essayé d'intégrer ma fonction de gestionnaire des messages Windows dans ce thread, mais les paramètres de cette fonction étant des TMessages, apparemment ça n'est pas pris.
Voici mon code pour créér le Thread :
Unit1.cpp :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
| //---------------------------------------------------------------------------
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <windows.h>
#include <winuser.h>
#include <windef.h>
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
RAWINPUTDEVICE Rid[1];
HRESULT hResult=0;
POINT cursor;
static float X = 0;
static float Y = 0;
static float cursorX, cursorY;
static float K = 0;
HANDLE hThread;
DWORD ThreadId;
int DataThread = 1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
if(Button1->Caption=="Démarrer")
{
GetCursorPos(&cursor);
cursorX = cursor.x;
cursorY = cursor.y;
Rid[0].usUsagePage = 1;
Rid[0].usUsage = 2;
Rid[0].dwFlags = RIDEV_NOLEGACY | RIDEV_INPUTSINK; // adds HID mouse and also ignores legacy mouse messages
Rid[0].hwndTarget = Handle;
hResult = RegisterRawInputDevices(Rid, 1, sizeof(Rid[0]));
if(FAILED(hResult)) ShowMessage("Erreur N°"+GetLastError());
hThread = CreateThread(NULL, 0, WMInput, &DataThread, 0, &ThreadId);
if(hThread==NULL)
ExitProcess(DataThread);
Button1->Caption="Arrêter";
}
else if(Button1->Caption=="Arrêter")
{
TerminateThread(hThread, ThreadId); //Stop the Thread
Button1->Caption="Démarrer";
}
}
//---------------------------------------------------------------------------
void __fastcall WMInput(TMessage &Message)
{
UINT dwSize;
GetRawInputData((HRAWINPUT)Message.LParam, RID_INPUT, NULL, &dwSize,sizeof(RAWINPUTHEADER));
LPBYTE lpb = new BYTE[dwSize];
if (GetRawInputData((HRAWINPUT)Message.LParam, RID_INPUT, lpb, &dwSize,
sizeof(RAWINPUTHEADER)) != dwSize ) {}
RAWINPUT* raw = (RAWINPUT*)lpb;
if (raw->header.dwType == RIM_TYPEMOUSE)
{
if((int)raw->header.hDevice>65607)
{
SetCursorPos(cursorX, cursorY);
X+= ((raw->data.mouse.lLastX)*2.54)/1000;
Y+= ((raw->data.mouse.lLastY)*2.54)/1000;
K=sqrt((X*X)+(Y*Y));
if(X+Y<0)
K = -K;
}
else
{
GetCursorPos(&cursor);
cursorX=cursor.x;
cursorY=cursor.y;
}
Form1->Edit1->Text=-K;
}
delete[] lpb;
}
//--------------------------------------------------------------------------- |
Unit1.h :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| //---------------------------------------------------------------------------
#define WM_INPUT 0x00FF
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // Composants gérés par l'EDI
TButton *Button1;
TEdit *Edit1;
void __fastcall Button1Click(TObject *Sender);
private: // Déclarations utilisateur
public: // Déclarations utilisateur
__fastcall TForm1(TComponent* Owner);
void __fastcall WMInput(TMessage &Message);
BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(WM_INPUT, TMessage, WMInput)
END_MESSAGE_MAP(TForm)
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif |
A la compilation, j'ai cette erreur-ci qui surgit du fin fond des abysses :
Code:
1 2
| [BCC32 Erreur] Unit1.cpp(47): E2034 Impossible de convertir 'unsigned long (__stdcall * (_closure )(void *))(void *)' en 'unsigned long (__stdcall *)(void *)'
[BCC32 Erreur] Unit1.cpp(47): E2342 Mauvaise correspondance de type dans le paramètre 'lpStartAddress' ('unsigned long (__stdcall *)(void *)' désiré, 'void' obtenu) |
Suite à ceci, j'en conclu donc qu'avec mon code, il m'est impossible de passer directement ma fonction WMINPUT dans le nouveau Thread, ma question est donc, comment faire pour effectuer cette fonction dans un Thread séparé du programme principal, afin de ne pas "figer" celui-ci sachant que la fonction est comme une boucle infinie ?
Cordialement.