Příznaky

Posuvník se nepřetržitě posouvá i po uvolnění levého tlačítka myši. Typ posuvníku je pro tento problém nevýznamný, to znamená, že ke stejnému problému dochází bez ohledu na to, jestli je posuvník součástí okna nebo jde o ovládací prvek posuvníku.

Příčina

K tomuto problému dochází obvykle v případě, že se smyčka při načítání zpráv zobrazuje jako výsledek akce pro posouvání při příjmu jedné z posouvaných zpráv posuvníku. Při posouvání se ve Windows spouští vnitřní smyčka načítání zpráv. Úkolem této zprávy je sledování posouvání a odeslání příslušných zpráv s oznámením posuvníku, WM_HSCROLL a WM_VSCROLL. Po přijetí WM_LBUTTONUP se posouvání zastaví. Pokud je během posouvání zahájená jiná smyčka zpráv, WM_LBUTTONUP se načte pomocí této smyčky zpráv a protože aplikace nemá přístup k internímu cyklu načítání zpráv posuvníku, WM_LBUTTONUP nepůjde správně odeslat. Z toho důvodu není WM_LBUTTONUP nikdy přijato interní zprávou a posouvání se nikdy neukončí. V aplikaci, která slouží k posouvání, není nutné, aby byl tento problém vyřešen. Když zavoláte některou z následujících funkcí nebo zpracování jakékoli zprávy s cyklem načítání zpráv, může při posouvání dojít ke ztrátě WM_LBUTTONUP. Níže uvedené funkce spadají do této kategorie:

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

Řešení

Při posouvání se WM_LBUTTONUP zpráva nenačítá z fronty, a to pomocí žádného dalšího opakování zpráv, než je vnitřní. Aplikace se mohou v tomto problému vysílat takto:

  • Aplikace implementuje smyčku načítání zpráv k implementaci zpracování na pozadí, například při zpracování na pozadí při provádění času, který maluje.

  • Aplikace implementuje smyčku načítání zpráv pro implementaci komunikace s jinou aplikací nebo DLL knihovnou. Aplikace například vyžaduje přijímání dat z jiného místa.

Možná alternativní řešení

Níže jsou uvedena dvě možná řešení. První alternativní řešení se používá při mnoha ukončování aplikací a v systému Windows. za výjimečných okolností však nemusí být první alternativní řešení možné. V tomto případě se dá použít druhé alternativní řešení. Pokud je to možné, můžete se ale pokusit, aby se při posouvání nedošlo k úplnému načítání zpráv.

  • Používejte zpracování založené na zprávách časovače. Rozdělte komplikované zpracování na menší úkoly a sledujte, kde každý úkol začíná a končí, a proveďte jednotlivé úkoly na základě zprávy časovače. Po dokončení všech součástí zpracování časovač ukončete. Příklad tohoto alternativního řešení najdete níže.

  • Implementujte smyčku pro načítání zpráv, ale ujistěte se, že se WM_LBUTTONUP nenačítá. Toho lze dosáhnout pomocí filtrů. Několik příkladů tohoto alternativního řešení najdete níže.

Příklad ukazující alternativní řešení 1

Aplikace má složitý postup malování. Když voláte ScrollWindow (), vygenerujete zprávy nátěr. Zpracování na pozadí probíhá během malování.

  1. Když se zobrazí zpráva WM_PAINT, postupujte takto:

    1. Volejte BeginPaint ().

    2. Zkopírujte neověřený Rect do globální proměnné Rect (třeba grcPaint), která se použije v kroku 2. Globální Rect grcPaint by představovala sjednocení dříve získaného Rect (grcPaint) a nového invalidované Rect (PS. rcPaint). Kód pro toto bude vypadat takto:

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

    4. Volejte EndPaint ().

    5. Nastavení časovače

    Tímto způsobem se negenerují žádné další zprávy WM_PAINT, protože nejsou k dispozici žádné neplatné oblasti a je nastaven časovač, který generuje WM_TIMER zprávy.

  2. Po přijetí WM_TIMER zprávě zkontrolujte globální proměnnou Rect. Pokud není prázdný, povezměte oddíl a malujte ho. Pak upravte globální proměnnou Rect tak, aby už nezahrnovala prodanou oblast.

  3. Po vyprázdnění globální proměnné Rect zrušte časovač.

Příklad ukazující alternativní řešení 2

Aplikace potřebuje získat některá data prostřednictvím DDE nebo jiného mechanismu z jiné aplikace, která se pak zobrazí v okně. Abyste se mohli posunout, aplikace potřebuje žádost požádat a získat data z serverové aplikace. Existují tři různé filtry, které můžete použít k nastavení PeekMessage () a získávání informací. Filtry se dají nastavit pomocí parametrů uFilterFirst a uFilterLast PeekMessage (). uFilterFirst Určuje zprávu Fist v oblasti, kterou chcete zkontrolovat, a uFilterLast Určuje poslední zprávu v oblasti, kterou chcete zkontrolovat.

  1. Zkontrolovat a načíst jenom související zprávy pro získání potřebných dat

  2. Kontrola WM_LBUTTONUP bez jejího odebrání z fronty; Pokud je ve frontě, přerušit. V opačném případě načtěte a odešlete všechny zprávy.

  3. Načíst všechny zprávy menší než WM_LBUTTONUP a větší než WM_LBUTTONUP, ale Nezískávat WM_LBUTTONUP

Další informace

Kroky pro reprodukci problému

Následující je posloupnost událostí vedoucích ke ztrátě WM_LBUTTONUP zprávy:

  1. Klikněte na posuvník pomocí myši.

  2. Krok 1 vygeneruje zprávu WM_NCLBUTTONDOWN.

  3. Krok 2 způsobí spuštění interní zprávy Windows. Tato smyčka zpráv vyhledává zprávy související s posuvníky. Cílem této zprávy je vygenerovat vhodné WM_HSCROLL nebo WM_VSCROLL zprávy. Po přijetí WM_LBUTTONUP se smyčka zpráv ukončí.

  4. Když obdržíte zprávu WM_HSCROLL nebo WM_VSCROLL, aplikace se přidělí na smyčku nebo volá funkce, které vedou k načtení zpráv.

  5. WM_LBUTTONUP se z fronty odebere pomocí smyčky zpráv zmíněné v kroku 4. WM_LBUTTONUP se pak odešle.

  6. Jako výsledek kroku 5 WM_LBUTTONUP zpráva odeslána jinde a vnitřní smyčka pro načítání zpráv zmíněná v kroku 3 ji neobdrží. Smyčka zpráv v kroku 3 hledá WM_LBUTTONUP pro zastavení posouvání. Přesunutí posuvníku pokračuje.

Potřebujete další pomoc?

Chcete další možnosti?

Prozkoumejte výhody předplatného, projděte si školicí kurzy, zjistěte, jak zabezpečit své zařízení a mnohem více.