flat assembler
Message board for the users of flat assembler.
Index
> Windows > Accessing the console buffer on windows |
Author |
|
revolution 19 Dec 2020, 12:14
For which OS?
|
|||
19 Dec 2020, 12:14 |
|
rc 19 Dec 2020, 12:17
For windows.
Sorry, forgot to mention. (Updated the thread) Last edited by rc on 19 Dec 2020, 12:19; edited 1 time in total |
|||
19 Dec 2020, 12:17 |
|
revolution 19 Dec 2020, 12:19
Moving to Windows forum.
Here is some old Windows code. I don't know if it works. Try it. Code: format pe console entry start include 'win32ax.inc' section '.code' code readable writeable executable start: invoke GetStdHandle,STD_OUTPUT_HANDLE mov [stdout],eax mov [rect.Left],0 mov [rect.Top],0 mov [rect.Right],79 mov [rect.Bottom],39 mov [coord.x],80 mov [coord.y],40 mov [cinfo.dwSize],25 mov [cinfo.bVisible],FALSE cinvoke system,<'cls'> cinvoke srand,<cinvoke time,NULL> invoke SetConsoleTitle,<'Random Pixels'> invoke SetConsoleWindowInfo,[stdout],1,rect invoke SetConsoleScreenBufferSize,[stdout],dword[coord] invoke SetConsoleCursorInfo,[stdout],cinfo invoke FindWindow,NULL,<'Random Pixels'> mov [hWnd],eax invoke GetDC,[hWnd] mov [hdc],eax @@: cinvoke rand shl eax,9 push eax cinvoke rand pop ecx add eax,ecx mov esi,eax invoke SetPixel,[hdc],<stdcall rnd,640>,<stdcall rnd,480>,esi cinvoke _kbhit test eax,eax jz @b invoke ExitProcess,0 proc rnd max cinvoke rand shl eax,17 mul [max] mov eax,edx ret endp section '.data' data readable writeable struc COORD { .x dw ? .y dw ? } struc SMALL_RECT { .Left dw ? .Top dw ? .Right dw ? .Bottom dw ? } struc LPCONSOLE_CURSOR_INFO { .dwSize dd ? .bVisible db ? } cinfo LPCONSOLE_CURSOR_INFO rect SMALL_RECT coord COORD stdout dd ? hWnd dd ? hdc dd ? section '.idata' import data readable writeable library kernel32,'kernel32.dll',\ msvcrt,'msvcrt.dll',\ user32,'user32.dll',\ gdi32,'gdi32.dll' import gdi32,\ SetPixel,'SetPixel' import user32,\ GetDC,'GetDC',\ FindWindow,'FindWindowA' import kernel32,\ ExitProcess,'ExitProcess',\ GetStdHandle,'GetStdHandle',\ SetConsoleTitle,'SetConsoleTitleA',\ SetConsoleCursorInfo,'SetConsoleCursorInfo',\ SetConsoleWindowInfo,'SetConsoleWindowInfo',\ SetConsoleCursorPosition,'SetConsoleCursorPosition',\ SetConsoleScreenBufferSize,'SetConsoleScreenBufferSize' import msvcrt,\ _kbhit,'_kbhit',\ system,'system',\ srand,'srand',\ rand,'rand',\ time,'time' |
|||
19 Dec 2020, 12:19 |
|
rc 19 Dec 2020, 12:32
Thanks for the quick reply.
This code compiles, however it has strange behavior. It draws random pixels on the desktop itself not in the console |
|||
19 Dec 2020, 12:32 |
|
revolution 19 Dec 2020, 12:36
Then I think the FindWindow call is returning zero.
Basically once you get the DC for a window then you can draw anything to it. In that code it just draws random pixels, but it could also be text or lines etc. |
|||
19 Dec 2020, 12:36 |
|
rc 19 Dec 2020, 13:16
Yes it returns zero, but dont know why.
I added a comparisson: Code: invoke SetConsoleScreenBufferSize,[stdout],dword[coord] invoke SetConsoleCursorInfo,[stdout],cinfo invoke FindWindow,NULL,<'Random Pixels'> cmp eax, 0 ; <--- je exit ; <--- mov [hWnd],eax invoke GetDC,[hWnd] mov [hdc],eax @@: cinvoke rand shl eax,9 push eax cinvoke rand pop ecx add eax,ecx mov esi,eax invoke SetPixel,[hdc],<stdcall rnd,640>,<stdcall rnd,480>,esi cinvoke _kbhit test eax,eax jz @b exit: invoke ExitProcess,0 |
|||
19 Dec 2020, 13:16 |
|
revolution 19 Dec 2020, 13:22
Calling GetLastError might show the reason.
|
|||
19 Dec 2020, 13:22 |
|
rc 19 Dec 2020, 13:58
Error is ERROR_INVALID_FUNCTION
Changed it to get the last error like this: (Sorry i am still a newb when it comes to assembly) Code: format pe console entry start include 'win32ax.inc' section '.code' code readable writeable executable start: invoke GetStdHandle,STD_OUTPUT_HANDLE mov [stdout],eax mov [rect.Left],0 mov [rect.Top],0 mov [rect.Right],79 mov [rect.Bottom],39 mov [coord.x],80 mov [coord.y],40 mov [cinfo.dwSize],25 mov [cinfo.bVisible],FALSE cinvoke system,<'cls'> cinvoke srand,<cinvoke time,NULL> invoke SetConsoleTitle,<'Random Pixels'> invoke SetConsoleWindowInfo,[stdout],1,rect invoke SetConsoleScreenBufferSize,[stdout],dword[coord] invoke SetConsoleCursorInfo,[stdout],cinfo invoke FindWindow,NULL,<'Random Pixels'> cmp eax, 0 je error mov [hWnd],eax invoke GetDC,[hWnd] mov [hdc],eax @@: cinvoke rand shl eax,9 push eax cinvoke rand pop ecx add eax,ecx mov esi,eax invoke SetPixel,[hdc],<stdcall rnd,640>,<stdcall rnd,480>,esi cinvoke _kbhit test eax,eax jz @b error: invoke GetLastError push eax push eax lea eax,[lpBuffer] invoke FormatMessage,FORMAT_MESSAGE_ALLOCATE_BUFFER or FORMAT_MESSAGE_FROM_SYSTEM or FORMAT_MESSAGE_ARGUMENT_ARRAY,NULL,1,LANG_NEUTRAL,eax,0,esp pop eax pop eax invoke MessageBox,NULL,[lpBuffer],NULL,MB_ICONERROR+MB_OK invoke LocalFree,[lpBuffer] exit: invoke ExitProcess,0 proc rnd max cinvoke rand shl eax,17 mul [max] mov eax,edx ret endp section '.data' data readable writeable lpBuffer dd ? struc COORD { .x dw ? .y dw ? } struc SMALL_RECT { .Left dw ? .Top dw ? .Right dw ? .Bottom dw ? } struc LPCONSOLE_CURSOR_INFO { .dwSize dd ? .bVisible db ? } cinfo LPCONSOLE_CURSOR_INFO rect SMALL_RECT coord COORD stdout dd ? hWnd dd ? hdc dd ? section '.idata' import data readable writeable library kernel32,'kernel32.dll',\ msvcrt,'msvcrt.dll',\ user32,'user32.dll',\ gdi32,'gdi32.dll' import gdi32,\ SetPixel,'SetPixel' import user32,\ GetDC,'GetDC',\ FindWindow,'FindWindowA',\ MessageBox,'MessageBoxA' import kernel32,\ ExitProcess,'ExitProcess',\ GetLastError,'GetLastError',\ FormatMessage,'FormatMessageA',\ LocalFree,'LocalFree',\ GetStdHandle,'GetStdHandle',\ SetConsoleTitle,'SetConsoleTitleA',\ SetConsoleCursorInfo,'SetConsoleCursorInfo',\ SetConsoleWindowInfo,'SetConsoleWindowInfo',\ SetConsoleCursorPosition,'SetConsoleCursorPosition',\ SetConsoleScreenBufferSize,'SetConsoleScreenBufferSize' import msvcrt,\ _kbhit,'_kbhit',\ system,'system',\ srand,'srand',\ rand,'rand',\ time,'time' |
|||
19 Dec 2020, 13:58 |
|
revolution 19 Dec 2020, 14:15
Does the title of the console change to "Random Pixels"?
You can also change the find string to the title of the console, instead of changing the title and then trying to find it. |
|||
19 Dec 2020, 14:15 |
|
rc 19 Dec 2020, 14:39
The strange thing is, a console window opens for a split of a second, closes and then a graphics window opens with the title "Random Pixels" and the pixels getting drawn somewhere else on the desktop. So the opened window is neither a console window nor powershell window.. its something else...
|
|||
19 Dec 2020, 14:39 |
|
revolution 19 Dec 2020, 14:45
If you delete the 'cls' call, and the three SetConsole*,[stdout],... calls, then the window will be used as-is, without changing the size.
The reason for drawing in the wrong place is the hWnd is zero (the desktop). |
|||
19 Dec 2020, 14:45 |
|
rc 19 Dec 2020, 15:19
Ok yes, it looks like changing the title and immediatly searching for a window with this title doesn't work. So searching for it multiple times works.
Code: format pe console entry start include 'win32ax.inc' section '.code' code readable writeable executable start: invoke GetStdHandle,STD_OUTPUT_HANDLE mov [stdout],eax mov [rect.Left],0 mov [rect.Top],0 mov [rect.Right],79 mov [rect.Bottom],39 mov [coord.x],80 mov [coord.y],40 mov [cinfo.dwSize],25 mov [cinfo.bVisible],FALSE ;cinvoke system,<'cls'> cinvoke srand,<cinvoke time,NULL> invoke SetConsoleTitle,<'Test_'> ;invoke SetConsoleWindowInfo,[stdout],1,rect ;invoke SetConsoleScreenBufferSize,[stdout],dword[coord] ;invoke SetConsoleCursorInfo,[stdout],cinfo mov ecx, 10 @@: dec ecx cmp ecx, 0 je error invoke FindWindow,NULL,<'Test_'> cmp eax, 0 je @b mov [hWnd],eax invoke GetDC,[hWnd] mov [hdc],eax @@: cinvoke rand shl eax,9 push eax cinvoke rand pop ecx add eax,ecx mov esi,eax invoke SetPixel,[hdc],<stdcall rnd,640>,<stdcall rnd,480>,esi cinvoke _kbhit test eax,eax jz @b jmp exit error: invoke GetLastError push eax push eax lea eax,[lpBuffer] invoke FormatMessage,FORMAT_MESSAGE_ALLOCATE_BUFFER or FORMAT_MESSAGE_FROM_SYSTEM or FORMAT_MESSAGE_ARGUMENT_ARRAY,NULL,1,LANG_NEUTRAL,eax,0,esp pop eax pop eax invoke MessageBox,NULL,[lpBuffer],NULL,MB_ICONERROR+MB_OK invoke LocalFree,[lpBuffer] exit: invoke ExitProcess,0 proc rnd max cinvoke rand shl eax,17 mul [max] mov eax,edx ret endp section '.data' data readable writeable lpBuffer dd ? struc COORD { .x dw ? .y dw ? } struc SMALL_RECT { .Left dw ? .Top dw ? .Right dw ? .Bottom dw ? } struc LPCONSOLE_CURSOR_INFO { .dwSize dd ? .bVisible db ? } cinfo LPCONSOLE_CURSOR_INFO rect SMALL_RECT coord COORD stdout dd ? hWnd dd ? hdc dd ? section '.idata' import data readable writeable library kernel32,'kernel32.dll',\ msvcrt,'msvcrt.dll',\ user32,'user32.dll',\ gdi32,'gdi32.dll' import gdi32,\ SetPixel,'SetPixel' import user32,\ GetDC,'GetDC',\ FindWindow,'FindWindowA',\ MessageBox,'MessageBoxA' import kernel32,\ ExitProcess,'ExitProcess',\ GetLastError,'GetLastError',\ FormatMessage,'FormatMessageA',\ LocalFree,'LocalFree',\ GetStdHandle,'GetStdHandle',\ SetConsoleTitle,'SetConsoleTitleA',\ SetConsoleCursorInfo,'SetConsoleCursorInfo',\ SetConsoleWindowInfo,'SetConsoleWindowInfo',\ SetConsoleCursorPosition,'SetConsoleCursorPosition',\ SetConsoleScreenBufferSize,'SetConsoleScreenBufferSize' import msvcrt,\ _kbhit,'_kbhit',\ system,'system',\ srand,'srand',\ rand,'rand',\ time,'time' |
|||
19 Dec 2020, 15:19 |
|
revolution 19 Dec 2020, 15:40
Perhaps a short Sleep might do the trick also.
Code: invoke Sleep,10 |
|||
19 Dec 2020, 15:40 |
|
rc 19 Dec 2020, 16:15
revolution wrote: Perhaps a short Sleep might do the trick also. Ok this does the trick, and looks even clearer. I need to pack this functionality into a dll so i can use it in c. Basically these few functions: - createConsoleWindow: title, x, y, width, height - setDrawColor: r, g, b (hex would also be ok) - drawPixel: x, y (will use the drawcolor) - clearConsole (will use the drawcolor) - getPressedKeyboardKey - getMouseX / getMouseY (gets mouse coordinates within the console window) - getPressedMouseKey Is this possible to do? |
|||
19 Dec 2020, 16:15 |
|
rc 19 Dec 2020, 17:34
Can someone tell me why this is throwing an error?
Dont know what i am suppose to use: edx, dx, dl, dh? I commented the line that is causing the error with: Code: ; <--- error: operand sizes do not match. Code: ; ############################################# ; HEADER ; ############################################# format pe console entry start ; ############################################# ; INCLUDES ; ############################################# include 'c:/fasm/include/win32ax.inc' ; ############################################# ; CODE ; ############################################# section '.code' code readable writeable executable start: invoke GetStdHandle,STD_OUTPUT_HANDLE mov [stdout],eax cinvoke srand, <cinvoke time, NULL> invoke initConsole, <'test_'>, 0, 0, 80, 40 cmp eax, 0 je error mov [hConsoleWnd],eax invoke GetDC,[hConsoleWnd] mov [hConsoleDc],eax @@: cinvoke rand shl eax,9 push eax cinvoke rand pop ecx add eax,ecx mov esi,eax invoke SetPixel,[hConsoleDc],<stdcall rnd,640>,<stdcall rnd,480>,esi cinvoke _kbhit test eax,eax jz @b jmp exit error: invoke GetLastError push eax push eax lea eax,[lpErrBuffer] invoke FormatMessage,FORMAT_MESSAGE_ALLOCATE_BUFFER or FORMAT_MESSAGE_FROM_SYSTEM or FORMAT_MESSAGE_ARGUMENT_ARRAY,NULL,1,LANG_NEUTRAL,eax,0,esp pop eax pop eax invoke MessageBox,NULL,[lpErrBuffer],NULL,MB_ICONERROR+MB_OK invoke LocalFree,[lpErrBuffer] exit: invoke ExitProcess,0 ; ############################################# ; PROCS ; ############################################# proc initConsole title:byte, x:dword, y:dword, w:dword, h:dword mov edx, [x] mov [rect.Left], edx mov edx, [y] mov [rect.Top], edx mov edx, [w] mov [coord.x], edx dec edx mov [rect.Right], edx mov edx, [h] mov [coord.y], edx dec edx mov [rect.Bottom], edx mov [cursorinfo.dwSize], 25 mov [cursorinfo.bVisible], FALSE cinvoke system, <'cls'> mov edx, [title] ; <--- error: operand sizes do not match. dx, dl, dh all do not work when i want to set the console title invoke SetConsoleTitle, edx invoke SetConsoleWindowInfo, [stdout], 1, rect invoke SetConsoleScreenBufferSize, [stdout], dword[coord] invoke SetConsoleCursorInfo, [stdout], cursorinfo invoke Sleep, 100 invoke FindWindow, NULL, title ret endp proc rnd max cinvoke rand shl eax,17 mul [max] mov eax,edx ret endp ; ############################################# ; DATA ; ############################################# section '.data' data readable writeable ; Error messages are stored here lpErrBuffer dd ? ; Stdout stdout dd ? ; Handle to console window hConsoleWnd dd ? ; Device context of console (used to perfom gdi functions) hConsoleDc dd ? struc VEC2D { .x dw ? .y dw ? } struc SMALL_RECT { .Left dw ? .Top dw ? .Right dw ? .Bottom dw ? } struc LPCONSOLE_CURSOR_INFO { .dwSize dd ? .bVisible db ? } cursorinfo LPCONSOLE_CURSOR_INFO rect SMALL_RECT coord VEC2D ; ############################################# ; IMPORTS ; ############################################# section '.idata' import data readable writeable library kernel32,'kernel32.dll',\ msvcrt,'msvcrt.dll',\ user32,'user32.dll',\ gdi32,'gdi32.dll' import gdi32,\ SetPixel,'SetPixel' import user32,\ GetDC,'GetDC',\ FindWindow,'FindWindowA',\ MessageBox,'MessageBoxA' import kernel32,\ Sleep,'Sleep',\ ExitProcess,'ExitProcess',\ GetLastError,'GetLastError',\ FormatMessage,'FormatMessageA',\ LocalFree,'LocalFree',\ GetStdHandle,'GetStdHandle',\ SetConsoleTitle,'SetConsoleTitleA',\ SetConsoleCursorInfo,'SetConsoleCursorInfo',\ SetConsoleWindowInfo,'SetConsoleWindowInfo',\ SetConsoleCursorPosition,'SetConsoleCursorPosition',\ SetConsoleScreenBufferSize,'SetConsoleScreenBufferSize' import msvcrt,\ _kbhit,'_kbhit',\ system,'system',\ srand,'srand',\ rand,'rand',\ time,'time' |
|||
19 Dec 2020, 17:34 |
|
Ali.Z 19 Dec 2020, 21:01
just use movzx.
_________________ Asm For Wise Humans |
|||
19 Dec 2020, 21:01 |
|
revolution 19 Dec 2020, 22:46
You have defined title as a byte; Which means your title can only be a single byte long. But you also have to zero terminate, so in fact now your title can only be zero bytes long with the zero terminator.
I think what you wanted was a pointer to a byte buffer. So the title parameter is a dword pointer, and you have the title stored somewhere else. Then you would change the FindWindow call to be [title] instead of the plain title. |
|||
19 Dec 2020, 22:46 |
|
Picnic 21 Dec 2020, 10:16
Hello,
rc, instead of FindWindow try GetConsoleWindow. See if that works. Code: invoke GetConsoleWindow mov [hWnd], eax rc wrote:
Yes i think it is possible. Take a look at Hobby Basic. It has rgb colors, mouse and keyboard support, resizable window, etc. You have to read more about microsoft's console functions. Here is a CLS routine to get you started. |
|||
21 Dec 2020, 10:16 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.