Edit control + WM_MOUSEMOVE



  • Hallo zusammen,
    wie kann man ein multiline Textfeld so zeichnen, dass es die Eigenschaften von WS_DISABLED hat, der "vertical scrollbar" aber aktiviert ist. ES_READONLY geht nicht, weil man innerhalb des Textfeldes keine WM_MOUSEMOVE-Nachrichten abfangen kann (und das ist für mich sehr wichtig). Ich will also, dass das Feld (mit Ausnahme des vert. scrollbar) deaktiviert ist und WM_MOUSEMOVE abgefangen werden kann.
    Danke.



  • Erstell doch eien subcalss - dann sollte es auch mit WM_MOUSEMOVE+ES_READONLY gehn.



  • Könntest du mal bitte schreiben, was du konkret möchtest? Soll das Kopieren des Textes nicht möglich sein?
    Eine visuelle Unterscheidung ziwschen readonly- und nornmalen Textfeldern wird auf Win 7 standardmäßig gar nicht durchgeführt (afair gab es das noch bei XP).

    Du könntest also einfach subclassen:

    WNDPROC GetDefaultWindowProc(HWND hwnd)
    {
    	return reinterpret_cast<WNDPROC>(GetWindowLongPtr(hwnd, GWL_USERDATA));
    }
    
    void SetWndProc(HWND hwnd, WNDPROC pWndProc)
    {
    	LONG_PTR old = GetWindowLongPtr(hwnd, GWL_WNDPROC);
    	SetWindowLongPtr(hwnd, GWL_USERDATA, old);
    	SetWindowLongPtr(hwnd, GWL_WNDPROC, reinterpret_cast<LONG_PTR>(pWndProc));
    }
    
    LRESULT CALLBACK EditProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
    	WNDPROC p = GetDefaultWindowProc(hwnd);
    	if(msg>=WM_MOUSEFIRST && msg<=WM_MOUSELAST)
    	{
    		SetCursor(LoadCursor(0, IDC_ARROW));
    		switch(msg)
    		{
    			case WM_LBUTTONDOWN:
    				SetFocus(hwnd);
    				return 0;
    			case WM_LBUTTONUP:
    				//ReleaseCapture();
    				HideCaret(hwnd);
    				return 0;
    			case WM_MOUSEWHEEL: // zulassen
    				break;
    			default:
    				return 0;
    		}
    	}
    	/*if(msg>=WM_KEYFIRST && msg<=WM_KEYLAST) // notfalls auch Tastatureingaben verwerfen
    		return 0;
    	*/
    	if(p)
    		return CallWindowProc(p, hwnd, msg, wParam, lParam);
    	return 0;
    }
    

    Und bei der Initialisierung des Fensters dann eben SetWndProc(GetDlgItem(hwnd, /*ID_DES_EDIT_CTRLS*/), EditProc); .

    Edit: ReleaseCapture() sollte wohl überflüssig sein, habe es nur aus "Gewohnheit" geschrieben.



  • Danke erstmal. Ich werde es mir in den nächsten Tagen in Ruhe anschauen.


  • Mod

    Grundsätzlich: Ein Fenster mit dem Stil WS_DISABLED bekommt niemals irgend welche Mausnachrichten!



  • Martin Richter schrieb:

    Grundsätzlich: Ein Fenster mit dem Stil WS_DISABLED bekommt niemals irgend welche Mausnachrichten!

    Das stimmt leider nicht. Ich kann sehr wohl Mausnachrichten innerhalb meines deaktivierten edit-Feldes abfangen!


  • Mod

    [Rewind] schrieb:

    Martin Richter schrieb:

    Grundsätzlich: Ein Fenster mit dem Stil WS_DISABLED bekommt niemals irgend welche Mausnachrichten!

    Das stimmt leider nicht. Ich kann sehr wohl Mausnachrichten innerhalb meines deaktivierten edit-Feldes abfangen!

    Nein!
    EnabledWindow
    http://msdn.microsoft.com/en-us/library/windows/desktop/ms646291(v=vs.85).aspx

    Enables or disables mouse and keyboard input to the specified window or control. When input is disabled, the window does not receive input such as mouse clicks and key presses. When input is enabled, the window receives all input.



  • Es ist mir völlig wurscht was da steht - ich sage, was ich sehe. So sieht der Code aus:

    // .rc
    IDR_MAINLPWND DIALOGEX 165, 15, 155, 160
    STYLE DS_SETFONT | WS_VISIBLE //| WS_SYSMENU
    FONT 8, "MS Sans Serif", 0, 0, 0x1
    BEGIN
        EDITTEXT        IDC_LPTEXT,0,9,135,150,ES_MULTILINE | WS_DISABLED | WS_VSCROLL
    
    END
    
    // .cpp: die dazugehörige WinProc
    BOOL CALLBACK lpWindowProc (HWND lpWindow, UINT Msg, WPARAM wParam, LPARAM lParam)
    {
        //...
    
    	switch(Msg)
    	{
        //...
    
    	case WM_INITDIALOG:
    		{
                    //...
    
    			return TRUE;
    		} break;
    
    	case WM_LBUTTONDOWN:
    		{
    			RECT mainWindowRect;
    			GetWindowRect (lpWindow, &mainWindowRect);
    
    			WORD cursorX = LOWORD(lParam);
    			WORD cursorY = HIWORD(lParam);
    
    			if (mainWindowRect.left + closeImageCoord.left <= cursorX &&
    				mainWindowRect.left + closeImageCoord.right >= cursorX &&
    				mainWindowRect.top + closeImageCoord.top <= cursorY &&
    				mainWindowRect.top + closeImageCoord.bottom >= cursorY)
    			{
    				is_closeDown = true;
    				return 0;
    			}
    
    			dragWindow = true;
    
    			SetCapture(lpWindow);
    			return 0;
    		} break;
    		//...
    

    Tja...



  • [Rewind] schrieb:

    Es ist mir völlig wurscht was da steht - ich sage, was ich sehe.

    Hmmm, das klingt nach einem überzeugten Ignoranten...

    Nun, Martin Richter hat 100%ig recht mit seiner Aussage. Ob Du es glaubst oder nicht. Ich jedenfalls kann seine Aussage in vollem Umfang bestätigen.

    Nun, was die Poster weiter oben meinten ist ein Subclassing des Edit-Controls. Und damit eine WndProc des Edit-Controls.

    Und nicht den WndProc eines Dialogs. Das sind zwei verschiedene Paar Schuhe!
    Nun, in Deinem WndProc lese ich

    case WM_INITDIALOG:
    

    und dies läßt meine Annahme zu, daß es sich um eine WndProc eines Dialogs (und nicht des Edit-Controls) handelt. Stimmts?

    Ich hoffe, damit das Mißverständnis hier aufgedeckt zu haben.

    Nun: Deine spezielle Frage mit nicht editierbarem Text und gleichzeitig funktionierendem Scrollbalken muß ich mangels Erfahrung passen.

    Wenn Du mit den Mausnachrichten nicht vorankommst, vielleicht kannst einen ganz anderen Ansatz verfolgen (nur mal eine Spontan-Idee von mir):
    Nimmst ein ganz normales Mutliline-Editfeld (enabled lassen), und Du fängst sämtliche Tastatureingaben ab. Natürlich per Subclassing (oben hab ichs erklärt welcher WndProc gemeint ist!)

    Aber Du müßtest vermutlich auch zusätzlich die Maus-Aktionen wie Drag&Drop oder Kopieren/Einfügen per Kontextmenü unterbinden... usw.

    HTH,
    Martin


  • Mod

    [Rewind] schrieb:

    Es ist mir völlig wurscht was da steht - ich sage, was ich sehe. So sieht der Code aus:
    ...
    Tja...

    Was Tja?
    Dir scheint nicht kalr zu sein, wer für das Rollen verantwortlich ist.
    Dir schint auch nicht klar zu sein, dass gerade weil Du das Fenster disabled hast gerade dann, die Nachrichten an das Parent weitergegeben werden und nicht an das Fenster.
    Und Dein Code zeigt nur eine Fensterprozedur, die ein Child hat...
    Der Rollbalken gehört aber gerade zu diesem Fenster, dass Du disablen willst! Und das geht eben nicht. Nichts anderes habe ich geschrieben.

    Da Du allerdings bereits klug bist benötigst Du meine Hilfe ja nicht...
    Für mich dann erstmal EOD.



  • Dennoch möchte ich mich bei euch bedanken.


Anmelden zum Antworten