בית
Top.Mail.Ru Yandeks.Metrika
פורום: "WinAPI";
ארכיון נוכחי: 2004.12.12;
הורדה: [xml.tar.bz2];

למטה

מדוע בעיה DispatchMessage AV? מצא סניפים דומים


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

בהליך, נוצר חלון נפרד עבור טקסט ההודעה, זרם נפרד, אירוע נשלח אליו, ואת פתיל הראשי הולך לחכות לאירוע להיות מוגדר:
P: = StrNew (PChar ("UpdThread")); נסה A: = CreateEvent (אפס, אמת, שקר, P); נסה נסה FUpdator.StopEvent: = A; FUpdator.Resume; לחזור חם MsgWaitForMultipleObjects (1, A, false, 2000, QS_AllINPUT) of Wait_Object_0: אם FUpdator.Stopped מכן הפסקה; אחר בזמן Peekmessage (M, 0, 0, 0, PM_REMOVE) להתחיל TranslateMessage (M); DispatchMessage (ז) ח ח עד FUpdator.Stopped סוף סוף סגוראנדלה (א) ח
אז, בשלב מסוים, DispatchMessage מתחיל להנפיק EAccessViolation. ההודעה המעובדת היא UM_SetUserText מותאמת אישית, שנשלח אל החלון שמושך את ההודעות. הודעות נשלחות מהזרם Updator בשיטות שלה לחלון התוכנית הראשי:
הליך TUpdator.DoOnStart (Msg: מחרוזת; שלב: מספר שלם; const Cnt: מספר שלם); var 22 ו להתחיל s: = Msg + "$" + IntToStr (שלב) + ":" + IntToStr (Cnt); אם FMsgHandle <> 0 לאחר מכן PostStrThreadMessage (FMsgHandle, UM_UpdatorStep, s) ח PostStrThreadMessage הוא הרחבה עבור PostThreadMessage כי rewrites את המחרוזת ב PChar (StrNew), ואת ההודעה UM_SetUserText נשלח לחלון Windows ב WndProc של החלון הראשי:
אם WaitFormHandle <> 0 מתחיל PostStrMessage (WaitFormHandle, WM_SetUserText, MsgText); PostMessage (WaitFormHandle, WM_Paint, 0,0) ח
אשר פשוט שואבת את PChar קיבל ומשחרר אותו. אני פשוט לא יכול להבין מדוע DispatchMessage כתוצאה של כל זה מייצר AV.



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

יש לך s - lock.variable, החיים של אשר שווה את החיים של התוכנית, שם הוא הכריז

במקביל, התוכנית מבצעת את שיחת הסינכרון של PostMessage, מעבירה את הכתובת של משתנה זה על ידי הפרמטר

מאז PostMessage הוא אסינכרוני, זה מעביר את המסר בתור הנמען ומסתיים שם, עקב אשר המשתנה זה מפסיק להתקיים

ברגע שהנמען מתחיל לעבד את המסרים האסינכרונים שנשלחו אליו, כתובת המחרוזת המופיעה בפרמטר ההודעה היא כבר קישור ל"שום מקום "

למטרות אלה, עליך להשתמש בשליחה הסינכרונית של הודעות (SendMessage)



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

Digitman ©:
אז אני rework את הקו ב PChar:
הליך PostStrMessage (aHandle: HWND; Msg: מספר שלם: S: string: const wP: integer = 0); var P: PChar; להתחיל P: = StrNew (PChar (s)); PostMessage (aHandle, Msg, wP, מספר שלם (P)) ח
האם הזיכרון שהוקצה ל StrNew נהרג גם?



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

לא כאן

לספק הצהרה / יישום מדויק של PostStrThreadMessage ()



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

מצטערים, העתקת את ההליך הבא. הקוד זהה:
הליך PostStrThreadMessage (aHandle: HWND; Msg: מספר שלם; S: מחרוזת; const wP: מספר שלם = 0); var P: PChar; להתחיל P: = StrNew (PChar (s)); PostThreadMessage (aHandle, Msg, wP, מספר שלם (P)) ח



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


> [4] אלכסנדר. (26.10.04 14: 21)

נראה שזה נכון. נסה LocalALoc + CopyMemory במקום StrNew



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


> ההודעה המעובדת מותאמת אישית
> UM_SetUserText


להביא את הקוד המלא של המעבד



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

Digitman ©:
אני מביאה. הפונקציה שמוגדרת בחלון המטפל. בממשק, המשתנים הגלובליים MainHandle, WaitFormHandle מצהירים - בעת יצירת הטופס, הידית של חלון האב של חלון החלון ואת חלון ה- API עצמו נכנסים אליהם. ביישום, FWaitText קבוע מודפס גלובלי, אשר מאחסן את התוכן של פלט הטקסט האחרון, ו WaitWidth, אשר מאחסן את רוחב שצוין בעת ​​היצירה.


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]

האם עקבות צעד אחר צעד את הגוף של המטפל um_SetUserText בהקשר של Windowproc ()? מה בדיוק קו מרגש excl?



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


> PostMessage (aHandle, Msg, wP, מספר שלם (P))


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

אתה מעביר את החבל לפארם, ואתה תופס אותו בווארם



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

Clickmaker ©:
שוב מטעה. כאשר הערות נכתבו, אני שפשף את הטקסט ואת זה סיימה את זה באופן ידני. כמובן lParam:
s: = StrPas (PChar (lParam)); StrDispose (PChar (lParam)); // הודעת טקסט שהתקבלה

Digitman ©:
העובדה היא שזה לא יוצר שגיאות שם. במובן זה, עצרתי ב- DispatchMessage, אני לוחץ על F7, וזה מטומטם מחליק אל השורה הבאה. והאם DispatchMessage גם להתקשר זה המטפל?



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


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


כאן אתה לא עצלן מדי לנתח חבורה של קוד של מישהו אחר)
המחבר לא להכות את האצבע, הם אומרים, AV כאשר מתקשר המשגר ​​- וזהו .. המוח של אנשים אחרים - הם תמיד nahalavku)



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


> האם DispatchMessage באמת קוראים המטפל מדי?


ואיזה מטפל אחר יהיה, לדעתך, סיבה, מלבד זה?
מה מותקן, וזה יגרום ..



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

Digitman ©:
הסיסמה הקומוניסטית יודעת? העשירים צריכים לשתף :). למי אלוהים נתן יותר מוחות ופחות עבודה, הוא מחולק.



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

Digitman ©:
אני, נאיבי, חשבתי כי TranslateMessage ...



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


> [14] אלכסנדר. (26.10.04 16: 32)
> Digitman ©:
> אני, נאיבי, האמין כי TranslateMessage ...

TranslateMessage מתרגמת קודי מפתח וירטואליים (כגון VK_) לתוך תו. העבודה העיקרית נעשית על ידי DispatchMessage



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

Clickmaker ©:
לחיות וללמוד. אני אדע ...



עמודים: 1 ענף שלם

פורום: "WinAPI";
ארכיון נוכחי: 2004.12.12;
הורדה: [xml.tar.bz2];

למעלה









זיכרון: 0.64 MB
זמן: 0.116 c
14-1099344694
ארזזר
2004-11-02 00:31
2004.12.12
VoIP וכל מה שקשור אליו


4-1098714567
רקסוול
2004-10-25 18:29
2004.12.12
הליך חלון ללחצן.


3-1100182085
} | {yk
2004-11-11 17:08
2004.12.12
פיירבירד


4-1099037024
Zsv
2004-10-29 12:03
2004.12.12
פרמטר בינארי


1-1101882072
Vav
2004-12-01 09:21
2004.12.12
הורדת נתונים ו- Ineta





אפריקאנס אלבני ערבי אַרְמֶנִי אזרביג'אן הבסקים בלארוסית בולגרי קטלאנית הסיני (פשוט) סינית (מסורתית) קרואטית צ'כיה דני הולנדי אנגלית אסטוני פיליפיני פיני צרפתית
גליציה גאורגיה גרמני יווני קריאולית האיטית עברי הינדי הונגרי איסלנדי אינדונזי אירי איטלקי יפני קוריאני לטבי ליטאי מקדוניה מלאית מלטזית נורבגי
פרסי פולני פורטוגזי רומנית רוסי סרבית סלובקי סלובני ספרדי סוואהילית שבדי תאילנדי תורכי אוקראיני אורדו ויאטנמית וולשית יידיש בנגלית בוסנית
קבואנו אספרנטו גוג'ראטית האוסה המונג איגבו יָאוָנִי קנאדה לחמר לאו הלטינית מאורים מרתי מונגולי נפאלית פונג'בית סומליה טמילית טלוגו יורובה
זולו
Английский Французский Немецкий Итальянский Португальский Русский Испанский