maison
Top.Mail.Ru Yandeks.Metrika
Forum: "WinAPI";
Archive actuelle: 2004.12.12;
Télécharger: [xml.tar.bz2];

vers le bas

Pourquoi DispatchMessage envoie-t-il un AV? Trouver des branches similaires


Aleksandr.   (2004-10-26 13:29) [0]

Dans la procédure, une fenêtre api pour les textes de message est créée, un flux séparé, un événement lui est transmis et le flux principal attend que l'événement soit défini:
P: = StrNew (PChar ("UpdThread")); essayer A: = CreateEvent (nil, true, false, P); essayer essayer FUpdator.StopEvent: = A; FUpdator.Resume; répéter case MsgWaitForMultipleObjects (1, A, false, 2000, QS_AllINPUT) de Wait_Object_0: si FUpdator.Stopped alors Pause sinon pendant que Peekmessage (M, 0, 0, 0, PM_REMOVE) commence TraduireMessage (M); DispatchMessage (M) fin fin jusqu'à FUpdator.Stopped enfin CloseHandle (A) fin
Donc, DispatchMessage commence à émettre EAccessViolation à un moment donné. Le message en cours de traitement est un UM_SetUserText personnalisé envoyé à la fenêtre qui dessine les messages. Les messages sont envoyés du flux Updator dans ses méthodes à la fenêtre principale du programme:
procedure TUpdator.DoOnStart (Msg: string; Step: Integer; const Cnt: Integer); var s: chaîne; commencer s: = Msg + "$" + IntToStr (Step) + ":" + IntToStr (Cnt); si FMsgHandle <> 0 alors PostStrThreadMessage (FMsgHandle, UM_UpdatorStep, s) fin , PostStrThreadMessage est un add-on pour PostThreadMessage, qui convertit une ligne en PChar (StrNew). Dans UndProc de la fenêtre principale, le message UM_SetUserText est envoyé à la fenêtre de l'application:
si WaitFormHandle <> 0 commence alors PostStrMessage (WaitFormHandle, WM_SetUserText, MsgText); PostMessage (WaitFormHandle, WM_Paint, 0,0) fin
qui dessine simplement le PChar résultant et le libère. Je n'arrive pas à comprendre pourquoi DispatchMessage à la suite de tout cela donne du contenu audiovisuel.



Digitman ©   (2004-10-26 13:38) [1]

vous avez s - une variable locale dont la durée de vie est égale à la durée de vie du programme où elle est déclarée

en même temps, le programme exécute l'appel asynchrone PostMessage, en passant l'adresse de cette variable avec le paramètre

PostMessage étant une fonction asynchrone, il place le message dans la file d'attente de destination et se termine immédiatement, si bien que la variable s cesse d'exister.

au moment où le destinataire commence à traiter le message asynchrone qui lui est envoyé, l'adresse de la ligne, qui est le paramètre du message, est déjà un lien vers "nulle part"

à cette fin, utilisez des messages d'envoi synchrones (SendMessage)



Aleksandr.   (2004-10-26 13:50) [2]

Digitman ©:
Alors je refais la chaîne dans PChar:
procedure PostStrMessage (aHandle: HWND; Msg: entier; S: chaîne; const wP: entier = 0); var P: PChar; commencer P: = StrNew (PChar (s)); PostMessage (aHandle, Msg, wP, Integer (P)) fin
Est-ce que la mémoire allouée par StrNew est également tuée?



Digitman ©   (2004-10-26 14:01) [3]

ici - non

donne la déclaration exacte / implémentation de PostStrThreadMessage ()



Aleksandr.   (2004-10-26 14:21) [4]

Désolé, j'ai copié la procédure suivante. Le code est le même:
procedure PostStrThreadMessage (aHandle: HWND; Msg: entier; S: chaîne; const wP: entier = 0); var P: PChar; commencer P: = StrNew (PChar (s)); PostThreadMessage (aHandle, Msg, wP, Integer (P)) fin



clickmaker ©   (2004-10-26 14:41) [5]


> [4] Aleksandr. (26.10.04 14: 21)

Tout semble être juste. Essayez LocalAlloc + CopyMemory au lieu de StrNew



Digitman ©   (2004-10-26 14:45) [6]


> Le message en cours de traitement est défini par l'utilisateur
> UM_SetUserText


donne le code complet du handler



Aleksandr.   (2004-10-26 15:31) [7]

Digitman ©:
Je l'apporte La fonction plantée par la fenêtre apish sur le gestionnaire. Les variables globales MainHandle, WaitFormHandle sont déclarées dans l'interface. Lors de la création du formulaire, le descripteur de la fenêtre parente de la fenêtre de l'application y est entré, ainsi que la fenêtre de l'API elle-même. En implémentation, la constante typée globale FWaitText, qui stocke le contenu du dernier texte affiché, et WaitWidth, qui stocke la largeur spécifiée à la création.


implementation

const
 FWaitText : string="";
 WaitWidth : integer=300;

function WindowProc(wnd:HWND; Msg : Integer; Wparam:Wparam; Lparam:Lparam) : Lresult; stdcall;
var
 R   : TRect;
 DC  : HDC;
 rgn : HRGN;
 s   : string;
 P   : size;
 Buf : PChar;
begin
 case msg of
   wm_Destroy : begin
                  ...
                  FWaitText:="";
                  MainHandle:=0;
                  WaitFormHandle:=0
                end;
  wm_Activate,
  wm_SetFocus,
  wm_ActivateApp,
  wm_MouseActivate,
  wm_NCLButtonDown :
                 begin
                   PostMessage(WaitformHandle,wm_SetUserText,Integer(StrNew(PChar(FWaitText))),0);
                   Result:=0
                 end;
   um_SetUserText :
                 begin
                   Result:=0;
                   DC:=GetDC(WaitFormHandle);
                   try
                     rgn:=CreateRectRgn(0,0,WaitWidth,70);
                     try
                       SetWindowRgn(WaitFormHandle,rgn,false);
                       FillRgn(DC,rgn,RGB(255, 0, 0));
                       R.Left:=0;
                       R.Top:=10;
                       R.Right:=WaitWidth;
                       R.Bottom:=70;
                       s:="";
                       repeat
                         s:=s+" ";
                         Buf:=StrNew(PChar(S));
                         try
                           GetTextExtentPoint32(DC,Buf,length(s),P)
                         finally
                           StrDispose(Buf)
                         end
                       until P.cx>=WaitWidth-2;
                       Buf:=StrNew(PChar(s));
                       try
                         DrawText(DC,PChar(Buf),-1,R,dt_Center+dt_VCenter);
                       finally
                         StrDispose(Buf)
                       end;
// залили пробелами по ширине, а то мусор от прежней записи остается
                       s:=StrPas(PChar(wParam));
                       StrDispose(PChar(wParam));
// получили текст сообщения
                       FWaitText:=s;
                       Buf:=StrNew(PChar(s));
                       try
                         DrawText(DC,Buf,-1,R,dt_Center+dt_VCenter+DT_END_ELLIPSIS)
                       finally
                         StrDispose(Buf)
                       end    
                     finally
                       DeleteObject(RGN)
                     end
                   finally
                     ReleaseDC(Wnd,DC)
                   end;
                   PostMessage(WaitFormHandle,wm_LButtonDown,0,0)// а это сообщение, чтобы она фокус получила
                 end
   else
     Result:=DefWindowProc(wnd,msg,wparam,lparam)
 end
End;



Digitman ©   (2004-10-26 16:01) [8]

avez-vous tracé pas à pas le corps du gestionnaire um_SetUserText dans le contexte de Windowproc ()? quelle ligne exclut spécifiquement?



clickmaker ©   (2004-10-26 16:15) [9]


> PostMessage (aHandle, Msg, wP, Integer (P))


> s: = StrPas (PChar (wParam));

Vous passez la chaîne à lParam, mais vous l'attrapez à wParam



Aleksandr.   (2004-10-26 16:29) [10]

clickmaker ©:
Encore trompé. Quand j'ai écrit des commentaires, j'ai frotté le texte et l'ai terminé à la main. Bien sûr, lParam:
s: = StrPas (PChar (lParam)); StrDispose (PChar (lParam)); // j'ai le texte du message

Digitman ©:
Le fait est qu'elle ne crée pas d'erreur ici. Je veux dire, je mets un point d'arrêt sur DispatchMessage, appuyez sur F7, et il passe bêtement à la ligne suivante. Mais DispatchMessage appelle-t-il également ce gestionnaire?



Digitman ©   (2004-10-26 16:29) [11]


> clickmaker © (26.10.04 16: 15) [9]


ici vous n'êtes pas trop paresseux pour analyser un tas de code d'autres personnes)
l’auteur n’a pas touché le doigt, dit-on, lorsqu’il appelle le répartiteur - et c’est tout… le cerveau des autres - ils sont toujours libres alors)



Digitman ©   (2004-10-26 16:31) [12]


> Mais DispatchMessage appelle-t-il également ce gestionnaire?


et quel autre gestionnaire pensez-vous appeler, à part cela?
qui est installé, cela causera ..



Aleksandr.   (2004-10-26 16:31) [13]

Digitman ©:
Connaissez-vous le slogan des communistes? Les riches doivent partager :). Il partage avec qui Dieu a donné plus de cerveaux et moins de travail.



Aleksandr.   (2004-10-26 16:32) [14]

Digitman ©:
Je, naïf, croyais que TranslateMessage ...



clickmaker ©   (2004-10-26 16:55) [15]


> [14] Aleksandr. (26.10.04 16: 32)
> Digitman ©:
> Je, naïf, pensais que TranslateMessage ...

TranslateMessage traduit les codes de clé virtuelle (ceux qui sont VK_) en codes de caractères. DispatchMessage fait l'essentiel du travail.



Aleksandr.   (2004-10-26 17:48) [16]

clickmaker ©:
Vivre et apprendre. Je saurai ...



Pages: 1 branche entière

Forum: "WinAPI";
Archive actuelle: 2004.12.12;
Télécharger: [xml.tar.bz2];

à l'étage









Mémoire: 0.64 MB
Heure: 0.077 c
4-1098642014
Point
2004-10-24 22:20
2004.12.12
comment remplacer une ressource


1-1101469896
chien de garde
2004-11-26 14:51
2004.12.12
Taborder


1-1101352153
Fktrc
2004-11-25 06:09
2004.12.12
Classe de sécurité du fil


3-1100590318
denis24
2004-11-16 10:31
2004.12.12
Suppression de photos dans le champ de tâches


3-1100096254
Andriy Tysh
2004-11-10 17:17
2004.12.12
Comment afficher un rapport QuickReport à partir de ClientDataSet uniquement pour ces enregistrements





afrikaans albanais Arabic arménien azerbaïdjanais basque Biélorusse Bulgare catalan Chinois simplifié) Chinois (traditionnel) croate Tchèque Danois Néerlandais Anglais estonien Filipino Finlandais Français
galicien géorgien Allemand Grecque Créole haïtien hébreu Hindi Hongrois Islandais Indonesian irlandais Italien Japonais Coréen letton lituanien macédonien Malay maltais Norvégien
persan Polonais Portugais roumain Russe serbe Slovaque Slovène Espagnol Swahili Suédois Thai turc ukrainien Urdu vietnamien gallois yiddish bengali bosniaque
Cebuano espéranto gujarati Hause hmong Igbo Javanais Kannada Khmer lao latin maori Marathi mongol népalais punjabi somali tamil telugu yoruba
zoulou
Английский Français Allemand Italien Португальский Русский Espagnol