Scrollender Text
-
Hallo zusammen,
ich möchte ein Static Control gerne scrollenden Text verpassen. Ich würde das im WM_PAINT-Ereignis machen aber wie komme ich denn an die Message, wenn das Static- Control auf einem vorgefertigten Dialog liegt? Oder muss ich das über das WM_PAINT vom Dialog verarbeiten?
Kann mir da jemand weiter helfen?
-
Du könntest das Control Subclassen. SetClassLong sollte Dir da weiterhelfen. Bzw. solltest Du SetClassLongPtr (wg. evtl. 64 Bit Pointern/Handles) nehmen.
Damit eine eigene WndProc zuweisen, WM_PAINT abfangen, verarbeiten, weiterreichen an DefWindowProc. Alle Nachrichten außer WM_PAINT natürlich auch weiterreichen.

-
Ich hab das mal probliert aber es will nicht so recht klappen.
BOOL CALLBACK DialogProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_INITDIALOG: OldScrollTextProc = (WNDPROC)SetClassLong(GetDlgItem(hwnd, IDC_STATIC6), GCL_WNDPROC, (LONG)ScrollTextProc); if(!OldScrollTextProc) ErrorExit("SetClassLong"); return FALSE; case WM_CLOSE: EndDialog (hwnd, 0); return TRUE; } return FALSE; } BOOL CALLBACK ScrollTextProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_PAINT: HDC hdc; RECT rc; PAINTSTRUCT ps; GetClientRect(hwnd, &rc); hdc = BeginPaint(hwnd, &ps); TextOut(hdc, 0, 0, "test", 4); EndPaint(hwnd, &ps); break; } return CallWindowProc(OldScrollTextProc, hwnd, message, wParam, lParam); }Hierbei kommt erstmal kein Fehler aber es wird beim neu zeichnen nie die neue ScrollTextProc aufgerufen.
Dann hatte ich noch eine andere Methode gefunden:
BOOL CALLBACK DialogProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_INITDIALOG: SetWindowLong(GetDlgItem(hwnd, IDC_STATIC6), GWL_STYLE, GetWindowLong(GetDlgItem(hwnd, IDC_STATIC6), GWL_STYLE ) | BS_OWNERDRAW); return FALSE; case WM_DRAWITEM: if(((DRAWITEMSTRUCT*)lParam)->hwndItem == GetDlgItem(hwnd, IDC_STATIC6)) { MessageBox(NULL, "test", "test", MB_OK); return(TRUE); } break; case WM_CLOSE: EndDialog (hwnd, 0); return TRUE; } return false; }Das hat aber genauso wenig funktioniert - WM_DRAWITEM wird nie aufgerufen.
Muss ich vielleicht selber noch etwas machen?
-
Ich habs jetzt:
OldScrollTextProc = (WNDPROC)SetWindowLongPtr(GetDlgItem(hwnd, IDC_STATIC6), GWLP_WNDPROC, (LONG)(LONG_PTR)(WNDPROC)ScrollTextProc);Allerdings haut da irgendetwas immernoch nicht ganz hin.
WM_PAINT wird nur einmal nach ShowWindow durchlaufen. Sobald der Text in dem Control geändert wird, wird es normal ohne meine extra Verarbeitung gezeichnet.
-
Hmm ich hoffe Ich hab dein prob richtig verstanden mit dem scrollenden Text aber ich denke WM_PAINT hilft dir da nich weiter. Da du ja nur WM_PAINT Messages bekommst wenn das Fenster neu gezeichnet werden muss.
Setzt dir doch einen Timer (SetTimer(..)) auf weiß ich 10ms oder so musst mal testen und zeichnest dann wenn du die Message WM_TIMER bekommst deine Nachricht neu.
Aber ka ob du das jetzt gebrauchen kannst.MfG schirrmie
-
Hmm, stimmt eigentlich. Es ist zwar trotzdem komisch, dass das nicht funktioniert aber eigentlich ist es auch egal, denn der Timer würde ja dafür sorgen, dass es immer neu gezeichnet wird.
-
Falls es jeamnden interessiert, so funktoiniert es:
void CALLBACK TimerScroll( HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime ) { HDC hdc; //Control Größe RECT rc; //Text Größe (von DrawText gefüllt) RECT rc2; memset(&rc2, 0, sizeof(RECT)); GetClientRect(hwnd, &rc); hdc = GetDC(hwnd); //Standard System-Schriftart setzen HGDIOBJ hfont; hfont = GetStockObject(DEFAULT_GUI_FONT); SelectObject(hdc, hfont); //Standard System-Hintergrundfarbe setzen SetBkColor(hdc, (COLORREF)GetSysColor(COLOR_BTNFACE)); //Text-Ausmaße berechnen DrawText(hdc, scrollText, strlen(scrollText), &rc2, DT_CALCRECT); scrollPos -= 2; //wenn Text komplett links raus ist, starte wieder von rechts if(scrollPos < -rc2.right) { scrollPos = rc.right; } //Text zeichnen ExtTextOut(hdc, scrollPos, 0, ETO_OPAQUE | ETO_CLIPPED, &rc, scrollText, strlen(scrollText), NULL); ReleaseDC(hwnd, hdc); }