IC4.0/WndBufMode



  • Ich kann mich nicht erinnern, dass ich so ein Problem hatte. Zeig mal den Code zur Ausgabe, vielleicht kann ich dann helfen.

    MfG SideWinder



  • Waere ja wirklich erfreulich, wenn dir dazu noch was einfaellt - ich bin damit echt langsam am verzweifeln. 😞

    Ok, also einmal den Code zur Ausgabe... Ist allerdings assembler...
    Naja, habe es in den Kommentaren in etwa in C-Code umgesetzt, fuer alle Faelle...

    UpdateTextCursor:        ; wird beim Verlassen der Ausgabefunktion aufgerufen
    
    	push	eax
    	push	edi
    	push	esi      ; einige Werte sichern - egal
    
    ; lpWriteRegion.top=lpWriteRegion.left=0;
    	mov	dword [lpWriteRegion], 0
    
    ; lpWriteRegion.right=79;
    ; lpWriteRegion.bottom=24;
    	mov	dword [lpWriteRegion + 4], 24 << 16 | 79
    
    ; Display0_ScreenBasePtr ist ein Zeiger auf ein 2Dim-Array aus diesen
    ; 4Byte Screen-Info-Dingern, das vorher entsprechend befuellt wird. Da man wie
    ; gesagt die Ausgabe manchmal lesen kann, scheint das Befuellen vor Aufruf
    ; dieses Codes korrekt zu funktionieren...
    
    ; WriteConsoleOutputA(hConsoleOutput, Display0_ScreenBasePtr, 25<<16|80, 0, &lpWriteRegion);
    	push	lpWriteRegion;
    	push	0
    	push	25<<16|80
    	push	dword [Display0_ScreenBasePtr]
    	push	dword [hConsoleOutput]
    	call	WriteConsoleOutputA
    
    ; // FlushFileBuffers(hConsoleOutput);
    ;	push	dword [hConsoleOutput]
    ;	call	FlushFileBuffers
    
    ; SetConsoleCursorPosition(hConsoleOutput, ((LastScreenPos>>1)/80)<<16|(LastScreenPos>>1)%80);
    ; Funktioniert in WinXP uebrigens genau so wenig wie CounsoleOutput
    	movzx	eax, word [LastScreenPos]
    	mov	ebx, 50h
    	shr	eax, 1
    	xor	edx, edx
    	div	ebx
    	shl	eax, 16
    	or	eax, edx
    	push	eax
    	push	dword [hConsoleOutput]
    	call	SetConsoleCursorPosition
    
    	pop	esi
    	pop	edi
    	pop	eax   ; Werte wieder zuruecksichern - auch egal
    
    ; return;
    ret
    


  • Was mir sofort auffällt: Das Sichern des Cursors kannst du dir sparen, da WriteConsoleOutput() den Cursor nicht versetzt *g*

    Gibts in deinen ASM-Programmen keine bessere Versionen? Ich benutze immer die wchar_t-Funktionen...

    Aber das hilft dir beides nicht weiter, ansonsten sieht mir alles Koscha aus, wenn der Funktionsaufruf klappt sollte das eigentlich sofort am Bildschirm zu sehen sein 😞

    MfG SideWinder



  • SideWinder schrieb:

    Was mir sofort auffällt: Das Sichern des Cursors kannst du dir sparen, da WriteConsoleOutput() den Cursor nicht versetzt *g*

    Jup, eben drum. Da mein code praktisch eine cout-Implementierung darstellt, setze ich so den Cursor hinter das zuletzt ausgegebene Zeichen. 🙂

    SideWinder schrieb:

    Gibts in deinen ASM-Programmen keine bessere Versionen? Ich benutze immer die wchar_t-Funktionen...

    Was heisst hier "bessere Versionen"? Wegen dem unicode? Wo waere denn da die Verbesserung oder der Vorteil, wenn ich eh nur ASCII-Zeichen verwende?
    Naja, aber aus Spass an der Freud koennte ich es eigentlich auch mal mit der UniCode-Version versuchen. Muesste eigentlich genauso funktionieren.

    SideWinder schrieb:

    Aber das hilft dir beides nicht weiter, ansonsten sieht mir alles Koscha aus, wenn der Funktionsaufruf klappt sollte das eigentlich sofort am Bildschirm zu sehen sein 😞

    Hm, jetzt wo du es sagst: Ich habe das ganze nochmal mit dem Olly durchleuchtet und das WriteConsoleOutA gibt ein ERROR_NOACCESS (000003E6) zurueck, genau wie das SetCursor oder FlushBuffers 😕
    Kann doch aber eigentlich nicht sein, dass man auf den mit GetStdHandle(STD_OUTPUT_HANDLE) geholten ScreenBuffer keinen Zugriff mit diesen Funktionen hat..??



  • Dann übergibst du die Parameter wohl falsch bzw. dein CHAR_INFO-Array ist zu klein/falsch dimensioniert.

    MfG SideWinder



  • Auch nach mehrmaligem Durchgehen kann ich nicht recht nachvollziehen, wo der Fehler liegen koennte.

    Ich gehe stark davon aus, dass die Parameterreihenfolge korrekt ist, das Array sollte auch gross genug sein - schliesslich lese ich vorher schon mit
    lpWriteRegion.left=lpWriteRegion.top=0;
    lpWriteRegion.right=79; lpWriteRegion=24;
    ReadConsoleOutputA(hConsoleOutput, Display0_ScreenBasePtr, 25<<16|80, 0, &lpWriteRegion);
    den ScreenBuffer ein, und das klappt auch unter XP problemlos... 😕

    Wird LastErr eigentlich bei jedem API-Aufruf neu gesetzt? Soll heissen: Wird das nach einem fehlerhaften Aufruf beim Naechsten auch wieder auf ERROR_SUCCESS zurueckgesetzt?

    Weil, dass WriteConsoleOutputA wegen irgendwelcher Macken in den Parametern einen Fehler schmeisst, koennte ich ja vielleicht noch nachvollziehen, aber weshalb schlaegt dann SetConsoleCursorPosition(hConsoleOutput, COORD(0,4)); fehl?



  • Nobuo T schrieb:

    Wird LastErr eigentlich bei jedem API-Aufruf neu gesetzt?

    Nicht jede API-Funktion macht das. Um sicherzugehen, musst Du vor jedem Aufruf via SetLastError () den LastErr selbst zurücksetzen.

    VOID SetLastError (
        DWORD dwErrCode 	// per-thread error code  
     );
    


  • Ooooojeeee... Den kleinen Racker zu finden hat mich diesmal aber echt so einige Haare gekostet. 😮
    Das Problem war offenbar, dass der Stack beim Aufruf der fehlschlagenden Funktionen nicht dword-aligned war. Da muss man erstmal drauf kommen... 🙄

    Danke auf jeden Fall an alle, die sich hier bemueht haben. 🙂



  • Das kann dir mit einer ordentlichen Programmiersprache nicht passieren 😉

    MfG SideWinder



  • Jaja. :p Wo bleibt denn da der Spass? 😉


Anmelden zum Antworten