Conectați-vă cu Microsoft
Conectați-vă sau creați un cont
Salut,
Selectați un alt cont.
Aveți mai multe conturi
Alegeți contul cu care doriți să vă conectați.

Simptome

Bara de defilare defilează continuu chiar și după ce eliberați butonul mouse-ului din stânga. Tipul de bară de defilare nu este relevant pentru această problemă, adică aceeași problemă apare indiferent dacă bara de defilare face parte din fereastră sau este un control al barei de defilare.

Cauză

Această problemă apare de obicei atunci când se execută o buclă de regăsire a mesajelor ca rezultat al acțiunilor întreprinse pentru defilare la primirea unuia dintre mesajele de notificare din bara de defilare. Atunci când defilați, se pornește o buclă internă de regăsire a mesajelor în Windows. Activitatea acestei bucle de mesaj este să țină evidența defilării și să trimiteți mesajele de notificare corespunzătoare din bara de defilare, WM_HSCROLL și WM_VSCROLL. Defilarea este terminată după ce WM_LBUTTONUP este primită. Dacă se pornește o altă buclă de mesaj în timpul defilării, WM_LBUTTONUP este regăsită prin bucla mesajului și, deoarece o aplicație nu are acces la bucla de regăsire a mesajului intern al barei de defilare, WM_LBUTTONUP nu poate fi expediată corect. Prin urmare, WM_LBUTTONUP nu este primit niciodată de către regăsirea mesajului intern, iar defilarea nu se termină niciodată. Aplicația care defilează nu trebuie să regăsească mesajele în mod explicit pentru a provoca această problemă. Dacă apelați oricare dintre următoarele funcții sau dacă procesați orice mesaj care are o buclă de regăsire a mesajelor, în timp ce defilați, poate provoca pierderea WM_LBUTTONUP. Funcțiile listate mai jos se încadrează în această categorie:

DialogBox() DialogBoxIndirect() DialogBoxIndirectParam() DialogBoxParam() GetMessage() MessageBox() PeekMessage()

Rezolvare

În timp ce defilați, mesajul de WM_LBUTTONUP nu trebuie regăsit din coada de așteptare de la o buclă de regăsire a mesajelor, alta decât cea internă a barei de defilare. O aplicație poate întâlni această problemă după cum urmează:

  • O aplicație implementează o buclă de regăsire a mesajelor pentru a implementa procesarea fundalului, de exemplu, procesarea fundalului în timp ce efectuați o pictură care consumă timp.

  • O aplicație implementează o buclă de regăsire a mesajelor pentru a implementa comunicarea cu altă aplicație sau DLL. De exemplu, pentru a defila, aplicația trebuie să primească date din altă parte.

Soluții posibile

Două soluții posibile sunt listate mai jos. Prima soluție este utilizată de mai multe aplicații de ieșire și de Windows; cu toate acestea, în situații rare, prima soluție poate să nu fie una fezabilă. În acest caz, se poate utiliza a doua soluție. Totuși, dacă este posibil, încercați să evitați să implementați complet recuperarea mesajelor în timp ce defilați.

  • Utilizați procesarea bazată pe mesaje cronometrare. Detaliați procesarea complicată în activități mai mici și țineți evidența locului în care începe și se termină fiecare activitate, apoi efectuați fiecare activitate pe baza unui mesaj de cronometrare. Atunci când toate componentele de procesare sunt finalizate, ucideți cronometrul. Vedeți mai jos un exemplu de soluție.

  • Implementați o buclă de regăsire a mesajelor, dar asigurați-vă că WM_LBUTTONUP nu este regăsită de acesta. Acest lucru poate fi realizat utilizând filtre. Vedeți mai jos câteva exemple ale acestei soluții.

Exemplu care demonstrează soluția 1

O aplicație are o procedură de vopsire complexă. Apelare ScrollWindow (), pentru a defila, generează mesaje Paint. Procesarea fundalului are loc în timp ce pictați.

  1. Atunci când primiți mesajul WM_PAINT procedați astfel:

    1. Apelați BeginPaint ().

    2. Copiați rectul nevalidat la o variabilă rectală globală (de exemplu, grcPaint) care va fi utilizată la pasul 2. Rectorul grcPaint global ar fi o Uniune a rectorului obținut anterior (grcPaint) și a noului rect invalid (PS. rcPaint). Codul pentru aceasta va semăna cu următorul:

               RECT grcPaint;    // Should be initialized before getting the                           // first paint message.            :            :         UnionRect(&grcPaint, &ps.rcPaint,&grcPaint);
    3. Apelați ValidateRect () cu PS. rcPaint.

    4. Apelați EndPaint ().

    5. Setați un cronometru.

    În acest fel, nu se mai generează mesaje WM_PAINT, deoarece nu există regiuni nevalide și se configurează un cronometru, care va genera mesaje WM_TIMER.

  2. La primirea unui mesaj de WM_TIMER, Verificați variabila rectală globală; Dacă nu este gol, luați o secțiune și pictați-o. Apoi ajustați variabila rectală globală, astfel încât să nu mai includă regiunea pictată.

  3. După ce variabila rectală globală este goală, ucideți cronometrul.

Exemplu care demonstrează soluția 2

O aplicație trebuie să obțină date prin DDE sau prin alt mecanism din altă aplicație, care se afișează apoi în fereastră. Pentru a defila, aplicația trebuie să solicite și să obțină datele dintr-o aplicație de server. Există trei filtre diferite care pot fi utilizate pentru a configura o PeekMessage () și a obține informațiile. Filtrele pot fi configurate utilizând parametrii uFilterFirst și uFilterLast din PeekMessage (). uFilterFirst specifică mesajul Fist din zona de verificat și uFilterLast specifică ultimul mesaj din zonă de verificat.

  1. Verificați și regăsiți doar mesajele asociate pentru obținerea datelor necesare.

  2. Căutați WM_LBUTTONUP fără a-l elimina din coadă; Dacă este în coada de așteptare, întrerupere. În caz contrar, regăsiți și expediați toate mesajele.

  3. Regăsiți toate mesajele mai mici decât WM_LBUTTONUP și mai mari decât WM_LBUTTONUP, dar nu regăsiți WM_LBUTTONUP.

Mai multe informații

Pașii pentru reproducerea problemei

În continuare se află secvența evenimentelor care conduc la pierderea mesajului WM_LBUTTONUP:

  1. Faceți clic pe bara de defilare utilizând mouse-ul.

  2. Pasul 1 generează un mesaj WM_NCLBUTTONDOWN.

  3. Pasul 2 determină o buclă de mesaj intern Windows de pornit. Această buclă de mesaj caută mesaje asociate cu barele de defilare. Scopul acestei bucle de mesaj este să genereze mesaje WM_HSCROLL sau WM_VSCROLL corespunzătoare. Bucla mesajului și defilarea se termină după ce WM_LBUTTONUP este primit.

  4. Atunci când primiți mesajul WM_HSCROLL sau WM_VSCROLL, aplicația se află într-o buclă de regăsire a mesajelor direct sau apeluri care au ca rezultat recuperarea mesajelor.

  5. WM_LBUTTONUP este eliminat din coada de așteptare de către bucla mesajului menționată la pasul 4. WM_LBUTTONUP este apoi expediat.

  6. Ca rezultat al pasului 5 WM_LBUTTONUP mesajul este expediat în altă parte și bucla internă de regăsire a mesajelor, menționată la pasul 3, nu o primește niciodată. Bucla mesajului din pasul 3 caută WM_LBUTTONUP pentru a opri defilarea. Deoarece nu este primit, bara de defilare continuă defilarea.

Aveți nevoie de ajutor suplimentar?

Doriți mai multe opțiuni?

Explorați avantajele abonamentului, navigați prin cursurile de instruire, aflați cum să vă securizați dispozitivul și multe altele.

Comunitățile vă ajută să adresați întrebări și să răspundeți la întrebări, să oferiți feedback și să primiți feedback de la experți cu cunoștințe bogate.

Au fost utile aceste informații?

Cât de mulțumit sunteți de calitatea limbajului?
Ce v-a afectat experiența?
Apăsând pe Trimitere, feedbackul dvs. va fi utilizat pentru a îmbunătăți produsele și serviciile Microsoft. Administratorul dvs. IT va avea posibilitatea să colecteze aceste date. Angajamentul de respectare a confidențialității.

Vă mulțumim pentru feedback!

×