The MASM Forum
General => The Workshop => Topic started by: zedd151 on August 30, 2022, 03:19:39 AM
-
Here is a procedure I made to easily BitBlt bitmaps for a game I'm creating.
So far I find it works well, and have found no errors while using it.
* Posting it here for further testing and critique.
The DrawBitmap prototype:
DrawBitmap proto :dword, :dword, :dword, :dword, :dword, :dword
The DrawBitmap procedure:
DrawBitmap proc hDC:dword, hBmp:dword, xc:dword, yc:dword, wd:dword, ht:dword
local hOld:dword, hMemDC:dword
invoke CreateCompatibleDC, NULL
mov hMemDC, eax
invoke SelectObject, hMemDC, hBmp ; select object to blit to hMemDC
mov hOld, eax
invoke BitBlt, hDC, xc, yc, wd, ht, hMemDC, 0, 0, SRCCOPY ; blit hMemDC to hDC
invoke SelectObject, hMemDC, hOld ; select object for deletion
invoke DeleteDC, hMemDC
ret
DrawBitmap endp
xc = x coordinate
yc = y coordinate
wd = image width
ht = image height
The rest should be self explanatory.
hMemDC is local to this procedure, created and deleted there.
Calling DrawBitmap from WM_PAINT:
... more code above not necessary for this example
.elseif uMsg == WM_PAINT
invoke BeginPaint, hWin, addr ps
mov hDC, eax
; ---- loop code would start here
invoke DrawBitmap, hDC, hBmpBack, 0, 0, 480, 572
invoke DrawBitmap, hDC, hBmpX, 88, 146, 140, 140
; ---- loop code would end here
invoke EndPaint, hWin, addr ps
... more code below not necessary for this example
I wrote this procedure mainly to more easily facilitate using a loop to display multiple bitmaps during runtime while minimizing the code in WM_PAINT. Not using a loop obviously, just demonstrating usage here.
edit = fixed error in the code
-
Hi Swordfish,
Your idea looks nice. :thumbsup:
-
Thanks Vortex
Here is an example using a loop as I mentioned in my post above:
include \masm32\include\masm32rt.inc
WinMain proto
CreateMain proto :dword, :dword, :dword, :dword
CenterMain proto :dword, :dword, :dword
WndProc proto :dword, :dword, :dword, :dword
DrawBitmap proto :dword, :dword, :dword, :dword, :dword, :dword
ww equ 500
wh equ 614
col1x equ 18
col2x equ 170
col3x equ 322
row1y equ 88
row2y equ 240
row3y equ 392
imgw equ 140
imgh equ 140
.data
hInstance dd 0
hWnd dd 0
hBmpBack dd 0
hBmpX dd 0
hBmpO dd 0
xpiece1 dd col1x
xpiece2 dd col2x
xpiece3 dd col3x
xpiece4 dd col1x
xpiece5 dd col2x
xpiece6 dd col3x
xpiece7 dd col1x
xpiece8 dd col2x
xpiece9 dd col3x
ypiece1 dd row1y
ypiece2 dd row1y
ypiece3 dd row1y
ypiece4 dd row2y
ypiece5 dd row2y
ypiece6 dd row2y
ypiece7 dd row3y
ypiece8 dd row3y
ypiece9 dd row3y
Class db "Window_CLASS", 0
DispName db "Untitled", 0
BackBmp db "background.bmp", 0
XBmp db "x.bmp", 0
OBmp db "o.bmp", 0
.code
DrawBitmap proc hDC:dword, hBmp:dword, xc:dword, yc:dword, wd:dword, ht:dword
local hOld:dword, hMemDC:dword
push ecx
invoke CreateCompatibleDC, NULL
mov hMemDC, eax
invoke SelectObject, hMemDC, hBmp ; select object to blit to hMemDC
mov hOld, eax
invoke BitBlt, hDC, xc, yc, wd, ht, hMemDC, 0, 0, SRCCOPY ; blit hMemDC to hDC
invoke SelectObject, hMemDC, hOld ; select object for deletion
invoke DeleteDC, hMemDC
pop ecx
ret
DrawBitmap endp
WndProc proc hWin:dword, uMsg:dword, wParam:dword, lParam:dword
local ps:PAINTSTRUCT, hDC:dword
.if uMsg == WM_CREATE
invoke LoadImage, 0, addr BackBmp, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE
mov hBmpBack, eax
invoke LoadImage, 0, addr XBmp, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE
mov hBmpX, eax
invoke LoadImage, 0, addr OBmp, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE
mov hBmpO, eax
invoke LoadImage, 0, addr BackBmp, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE
mov hBmpBack, eax
.elseif uMsg == WM_PAINT
invoke BeginPaint, hWin, addr ps
mov hDC, eax
invoke DrawBitmap, hDC, hBmpBack, 0, 0, 480, 572 ; draw background image
; -----------------------------------
push esi
push edi
xor ecx, ecx
lea esi, xpiece1
lea edi, ypiece1
@@:
mov eax, [esi+ecx*4]
mov edx, [edi+ecx*4]
invoke DrawBitmap, hDC, hBmpX, eax, edx, imgw, imgh ; draw pieces into "squares"
inc ecx
cmp ecx, 9
jnz @b
pop edi
pop esi
; ------------------------------
invoke EndPaint, hWin, addr ps
.elseif uMsg == WM_CLOSE
invoke PostQuitMessage, 0
return 0
.endif
invoke DefWindowProc, hWin, uMsg, wParam, lParam
ret
WndProc endp
WinMain proc
local msg:MSG
invoke GetModuleHandle, 0
mov hInstance, eax
invoke CreateMain, 0, addr Class, addr WndProc, 0
mov hWnd, eax
invoke CenterMain, hWnd, ww, wh
invoke ShowWindow, hWnd, SW_SHOWNORMAL
invoke UpdateWindow, hWnd
invoke SetWindowText, hWnd, addr DispName
StartLoop:
invoke GetMessage, addr msg, 0, 0, 0
cmp eax, 0
je ExitLoop
invoke TranslateMessage, addr msg
invoke DispatchMessage, addr msg
jmp StartLoop
ExitLoop:
invoke ExitProcess, 0
ret
WinMain endp
CreateMain proc hI:dword, cn:dword, wp:dword, ic:dword
local wc:WNDCLASSEX, hIcon:dword, rct:RECT
mov hIcon, 0
cmp ic, 0
jz @f
invoke LoadIcon, hI, ic
mov hIcon, eax
@@:
mov wc.cbSize, sizeof WNDCLASSEX
mov wc.style, CS_BYTEALIGNWINDOW
mrm wc.lpfnWndProc, wp
mov wc.cbClsExtra, 0
mov wc.cbWndExtra, 0
mrm wc.hInstance, hI
mov wc.hbrBackground, COLOR_BTNFACE+2
mov wc.lpszMenuName, 0
mrm wc.lpszClassName, cn
mrm wc.hIcon, hIcon
invoke LoadCursor, 0, IDC_ARROW
mov wc.hCursor, eax
mrm wc.hIconSm, hIcon
invoke RegisterClassEx, addr wc
invoke CreateWindowEx, 528, cn, 0, 0CF0000h, 0, 0, 0, 0, 0, 0, 0, 0
ret
CreateMain endp
CenterMain proc hWin:dword, wd:dword, ht:dword
local rct:RECT, x:dword, y:dword
invoke SystemParametersInfoA, SPI_GETWORKAREA, 0, addr rct, 0
mov eax, rct.right
sub eax, wd
shr eax, 1
mov x, eax
mov eax, rct.bottom
sub eax, ht
shr eax, 1
mov y, eax
invoke MoveWindow, hWin, x, y, wd, ht, TRUE
ret
CenterMain endp
end WinMain
Yes, it draws the exact same piece so player "X" wins 8 ways. :joking:
Well, when I code the loop in the game I will read a buffer to determine which bitmap gets displayed in each square. :tongue:
Now I will work on making a nifty procedure to get the mouse coordinates and convert them to "square" x/y coordinates or better still the index to the game board.
Example source code in attachment below
edit = fixed error in the code in attachment. here (http://masm32.com/board/index.php?topic=10303.msg112674#msg112674)
-
Now I will work on making a nifty procedure to get the mouse coordinates and convert them to "square" x/y coordinates or better still the index to the game board.
You're talking about "hit testing". Here's the procedure in pseudocode:
Hit Testing
-----------
row=0
col=o
getMouseX, getMouseY
hitTestTop = 0
hitTestLeft= 0
hitTestBottom = $cellHeight
hitTestRight = $cellWidth
loop count = $total # of cells
loopTop:
if MouseX < hitTestLeft
break
if MouseY < hitTestTop
break
if MouseX > hitTestRight
break
if MouseY > hitTestBottom
break
; At this point, we have a hit:
; exit with (row, col)
row++
hitTestTop += $cellHeight
hitTestBottom += $cellHeight
if row > $maxRow
hitTestTop = 0
hitTestBottom = $cellHeight
hitTestLeft += $cellWidth
hitTestRight += $cellWidth
row=0
col++
LOOP loopTop
; Sadly, at this point we have no hit ...
Items starting with "$" are constants (the width & height of your "cells", the on-screen areas you want to hit-test for).
You're basically constructing a rectangle (the RECT structure comes in handy here) that you slide around the screen until the mouse coords. fall within it. Easy peasy.
When you find a hit, the row and col variables will tell you which "cell" was hit.
-
You're talking about "hit testing"...
Yes. But too late, I've got code:
GetIndex proc lParam:dword ; convert mouse coordinates to index value
mov eax, -1
mov ecx, lParam
mov edx, ecx
movzx ecx, cx
shr edx, 16
; convert mouse coordinates to square x/y coordinates
.if ecx >= col1x && ecx <= col1x+imgw
mov ecx, col1x
.elseif ecx >= col2x && ecx <= col2x+imgw
mov ecx, col2x
.elseif ecx >= col3x && ecx <= col3x+imgw
mov ecx, col3x
.endif
.if edx >= row1y && edx <= row1y+imgh
mov edx, row1y
.elseif edx >= row2y && edx <= row2y+imgh
mov edx, row2y
.elseif edx >= row3y && edx <= row3y+imgh
mov edx, row3y
.endif
; convert square x/y coordinates to index value
.if ecx == col1x && edx == row1y
mov eax, 0
.elseif ecx == col2x && edx == row1y
mov eax, 1
.elseif ecx == col3x && edx == row1y
mov eax, 2
.elseif ecx == col1x && edx == row2y
mov eax, 3
.elseif ecx == col2x && edx == row2y
mov eax, 4
.elseif ecx == col3x && edx == row2y
mov eax, 5
.elseif ecx == col1x && edx == row3y
mov eax, 6
.elseif ecx == col2x && edx == row3y
mov eax, 7
.elseif ecx == col3x && edx == row3y
mov eax, 8
.endif
ret
GetIndex endp
And
.elseif uMsg == WM_LBUTTONUP
invoke GetIndex, lParam
mov indx, eax
lea ecx, board
.if byte ptr [ecx+eax] == 0
mov byte ptr [ecx+eax], 1
.endif
.if indx != -1
invoke InvalidateRect, hWin, 0, 0
.endif
Using lParam from WM_LBUTTONUP but thanks for the offer.
At this rate, Ill have finished writing Tic Tac Toe here in this thread. :toothy:
-
OK, you like the "if ... elseif ... elseif ... elseif ...", ad infinitum approach. I prefer a nice clean block of code with a looping construct, without all those conditionals. More generalized (i.e., no need to rewrite substantially if the size of your grid changes).
Different stroke for different folks ...
-
Different stroke for different folks ...
I tend to stick with things I know. Yes I'm kinda .iffy... :tongue:
-
I prefer a nice clean block of code
Switch_ (https://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1285)
The Masm32 switch macro is also pretty powerful.
-
I prefer a nice clean block of code
Switch_ (https://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1285)
The Masm32 switch macro is also pretty powerful.
prefer the masm32 switch without needing lots of breaks;
mov ebx,x
mov edi,y
Switch alpha ;0-7
case 0
add ebx,cellxsize
case 1
add ebx,cellxsize
add edi,cellysize
case 2
add edi,cellysize
case 3
sub ebx,cellxsize
add edi,cellysize
case 4
sub ebx,cellxsize
case 5
sub ebx,cellxsize
sub edi,cellysize
case 6
sub edi,cellysize
case 7
add ebx,cellxsize
sub edi,cellysize
endsw
-
"A conditional expression by any other name still resolves to jumps n calls"
- dedndave
*Okay he never actually said that.
But he also wasn't a huge fan of .if blocks either iirc. He mentioned that in a post somewhere in the forum. I came across it recently while browsing some of the older threads. Can't remember the topic though.
Edit = I found it the Real quote from dedndave tm:
i prefer to write code "old style"
i am not too fond of .if/.else or .while/.endw stuff
but - the members don't like it when i write code that way - lol
so - to make code that i like - and that makes them happy,
i have had to learn how the statements work - in reverse
in other words, i write some code, disassemble it, and learn what code is generated
then - i write code they like - that more or less does what i wanted, to begin with
I miss Dave. He was my "go to guy" when I didn't understand the 'how and why' of a particular concept, piece of code, obscure (to me anyway) instructions, etc. He would give in depth explanations with examples. I hope he's doing well.
-
Software coders: What is a programming language that you hope never to work in again, and why? (https://www.quora.com/Software-coders-What-is-a-programming-language-that-you-hope-never-to-work-in-again-and-why/answer/Alexander-Feterman)
* COBOL. Verbose like no other, excess structure, unproductive, obtuse, limited, rigid.
* JavaScript. Insane semantics, weak typing, silent failure.
* BASIC. Mandatory line numbering. Zero standardization. Not even a structured language — you’ve never seen that much spaghetti code.
Strangely enough, "pure MASM" does not appear in the list. If you refuse .if ... .endif constructs, you vote for the worst variant of spaghetti code, worse than what BASIC abandoned 30 years ago by introducing structured programming.
The Masm32 SDK switch macro is a fine animal. It's much better than its C/C++ equivalent, basically because Hutch came from PowerBasic and laughed at Kernighan & Ritchie's break nonsense.
Switch_ (https://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1285) is more sophisticated (under the hood it's 264 lines, 5703 bytes of purest MASM code), but in real life you rarely need such luxury.
Btw for very simple, short hello world proggies you don't need switch or Switch_. Really, you might not even need .if ... endif or .While ... .Endw. Up to, say, 100 lines of code, it's fun to reflect every time whether jg or jb is the right mnemonic for your specific case. And given that nobody is interested in such short exercises, readability is not even an issue :cool:
-
Software coders: What is a programming language that you hope never to work in again, and why? (https://www.quora.com/Software-coders-What-is-a-programming-language-that-you-hope-never-to-work-in-again-and-why/answer/Alexander-Feterman)
* COBOL. Verbose like no other, excess structure, unproductive, obtuse, limited, rigid.
I'm here to register a hearty rebuttal to that insult against COBOL. I actually was a COBOL programmer (got paid for it even) for a short while. It was the 2nd language I learned, after BASIC (on the first IBM PC).
COBOL is actually very well suited for its tasks. It's extremely easy to read, which is maybe even more important than being easy to write (have you ever heard of a little thing called "maintenance"?).
And I'd really like to see some snot-nosed, pimple-faced kid write a robust, reliable and maintainable payroll program--something that people rely on for their paychecks--in C++ or Python or Pascal or whatever.
I liked COBOL.
-
@jj lol.
I'll stick to my .iffy code. (Pun intended) :biggrin:
Manually writing even the compares in WndProc would present a challenge in certain instances (multiple nested .if code for example) so, I don't want to go THAT far. Lol
I've seen plenty of code of that type in olly. What a mess. A lot of jumps that will never execute, etc. I did experiment whit discrete calls and jumps at various stages of my learning of assembly. The code ain't pretty no matter what lenses you look at it with. :toothy: Fortunately I removed all such code from my archives.
My very first piece of assembly code was a simple message box written in ollydbg. lol
I overwrote the original program, and figured out pointers, etc. :nie: this was long before I discovered masm32 btw, and that was a profound life changing moment.
-
There are alternatives to switch /case,
Lea pointer arithmetic and arrays of deltax, deltay,hicon,bitmap handle for 0-7 directions
Jumptable
But I choose switch /case because more readable easier to debug than array s
When using comisd it's simpler only zero flag and carry flag conditional jumps that's is used
-
There are alternatives to switch /case,
Lea pointer arithmetic and arrays of deltax, deltay,hicon,bitmap handle for 0-7 directions
Jumptable
Under the hood of Switch_:
004011C6 . 83F9 10 cmp ecx, 10
004011C9 .^ 7E B1 jle short MbCase0_7
004011CB > 83F9 FE cmp ecx, -2 ; Switch (cases -2..12, 5 exits)
004011CE .^ 7C BB jl short MbCase0_D
004011D0 . 83F9 12 cmp ecx, 12
004011D3 .^ 7F B6 jg short MbCase0_D
004011D5 .^ FF248D E41140 jmp near [ecx*4+4011E4] ; ******* the jumptable ***********
004011DC . 40114000 dd MbCase0_3
004011E0 . 8B114000 dd MbCase0_D
004011E4 . 4F114000 dd MbCase0_4
004011E8 . 8B114000 dd MbCase0_D
004011EC . 8B114000 dd MbCase0_D
004011F0 . 8B114000 dd MbCase0_D
004011F4 . 8B114000 dd MbCase0_D
004011F8 . 8B114000 dd MbCase0_D
But a jumptable rarely makes sense, see Rem under Switch_ (https://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1285)
If you find jumptables interesting, see older threads here (http://masm32.com/board/index.php?topic=5163.0) and here (http://masm32.com/board/index.php?topic=1185.0)
-
.switch, switch, Switch, switch_, et. al.
Which switch? :tongue:
.if
Only one? (IF/IFNDEF,etc isnt the same, so not included) No confusion there. :biggrin:
Hmmm.
I still prefer reading .iffy code. Not a commentary (yes it is :tongue: iffy code lol ) on coding styles.
And I rarely use .while on purpose.
At any rate, the "if/switch" debate should have its own thread imo. :icon_idea:
.else
I shall start posting all my code using cmp/jmp style coding :badgrin:
and using push/call too for good measure. :toothy: I've got a qeditor plugin for that (invoke to push/call)
.endif
edited for clarification. And indenting pseudo if block
-
I shall start posting all my code using cmp/jmp style coding :badgrin:
You laugh, but some of us (me) actually prefer the cmp/jxx style. Here's how I like to lay out my message dispatchers:
MOV EAX, uMsg
CMP EAX, WM_COMMAND
JE do_command
CMP EAX, WM_LBUTTONDOWN
JE do_lbuttondown
CMP EAX, WM_NOTIFY
JE do_notify
CMP EAX, WM_PAINT
JE do_paint
. . .
do_command:
MOV AX, WORD PTR wParam
CMP AX, IDOK
JE do_processing
CMP AX, IDCANCEL
JE do_close
. . .
do_lbuttondown:
; (big block of code here)
do_notify:
; (another big block o'code)
do_paint:
; (more big blox of code)
Let's compare to the .if/.elseif style:
switch umsg
case WM_COMMAND
DO this
DO that
; (big block of code)
case WM_LBUTTONDOWN
DO this
DO that
DO the_other
; (another big block o'code)
case WM_NOTIFY
DO this
DO that
; you get the idea ...
Better? Worse? Six of one and half a dozen of the other? I'd say my method is nicer because it keeps those big blocks of code (like the WM_PAINT) handler out of the dispatcher code, which after all is just a dispatcher: "WM_CREATE, here's your paycheck, WM_PAINT, here's your mail, ...". If the blocks are small enough then maybe I could see putting them in .if blocks, nicely indented of course. (I don't use indentation in my code at all. After all, this ain't C, it's assembly language ...)
(You'll have to excuse the probably-incorrect syntax in the switch/case example, as I don't know the proper syntax offhand since I don't use it.)
-
I have no problem with how anyone writes their conditional statements (if, while, switch, etc) Everyone has their own personal preferences sometimes due to their previous use of other programming languages. Just being a bit sarcastic in my last post. No worries, no discrete cmp and jxx in my code unless it provides a distinct advantage.
But indentation now is another topic (off topic too btw, but ok)
Indentation in the right places helps to clarify the code a bit, makes it more readable imo. Makes finding labels for example easier. Also easier to separate nested code (if, switch, while blocks, etc) Just another formatting preference, as is strategically placing an empty line in just the 'right' places.
-
Well, using those block-structured constructs (.if, .while, switch/case) pretty much implies indented code, that is if you want it to be easily readable and understandable. I totally get why C and other languages are indented that way. Just not the way I like to format my code.
-
That's fine too. Coding is a tad faster without it I'd imagine.
I'm sort of in the same boat as dedndave, in that I generally reformat others' code to what I'm used to. I once had a qeditor plugin that could do that, but it failed in nested if blocks. So a rewrite might be in the works at some point. It's nowhere near ready for the masses. lol
One thing that bugs me though... Those extra long lines of code. "qeditor", which I use doesn't have a word wrap option. That makes viewing 'wide' lines of code difficult. I feel as if the line of code would spill out into my desk from the right side of my monitor and drop all the ascii characters there. :joking: But that's another issue for another day.
I wonder if I could make a qeditor plugin for adding word wrap... thinking... (insert progress loop here)
-
I'll tell you what would make a really kewl editor plugin: the ability to select columns of text instead of the normal row-oriented block selection.
My all-time favorite editor, Multi-Edit, which unfortunately no longer runs on Windoze (at least my ancient copy) had this capability. Comes in really handy when trying to extract stuff from tables, or just for switching around large blocks of text. (It also had a magnificent macro language that you could extend with custom code to make the program do just about anything you wanted.)
I'm actually working on a custom edit control which can do this, but it's a pretty ambitious undertaking ... maybe someday?
-
maybe someday?
Would have to be in the not near future, as I have a full plate so to speak.
What format would this table be in? (comma, semicolon, space or other?) seperated values ?)
Another thing I hate are 'hard' tabs, (09h) qeditor has indent functions that don't first convert the tabs to spaces (yes qeditor issue) I do have a plugin (untab) for that purpose. And needless CAPITALIZATION where lowercase is still valid in masm (We're no longer in the MSDOS/Win3.1 era fortunately). I have (uncap) for that, which reminds me I found more items that could be converted to lowercase.
Anyway if/when I decide to go back into creating plugins (I'll look into your suggestion at that time), I'll create a topic for it and post them.
edited to add:
Damn, I just noticed I have 995 posts already. I wanted to save the 1000th post for my birthday Friday. (sargent swordfish gets another stripe :toothy: )
-
In RichMasm, you can select a block of text and then, using Tab and Shift Tab, shift the whole block right or left. That doesn't allow to extract columns from tables, but actually I would rarely see a need for that.
What I would desperately miss in any editor are things like
- a listbox with the matches of a find operation (->img (http://masm32.com/board/index.php?topic=5314.0))
- persistent bookmarks
- Alt left arrow/right arrow to jump between the last places visited
- individual colouring, see below
As you can see, I also use push push call occasionally - but I keep track with white background :cool:
-
In RichMasm, you can select a block of text and then, using Tab and Shift Tab, shift the whole block right or left.
Whether it has 'hard tabs' or simple spaces? If so, kewl. But I still like qeditor. :greensml:
-
The factor that sticks in my head for using pseudo high level constructions is decluttering a code source, especially if what you are writing is very complex. A UI application in Windows has a substantial amount of complex code and when you have to process at least dozens of messages that are sub-split like nested WM_COMMAND message, using PUSH / CALL notation becomes a nightmare.
I have in the past prototyped using a lookup table for branching through message processing and a WndProc() is very clear when done that way but they are messy and complex to set up where a switch block is clean, tidy and easy enough to read if its formatted properly.
-
Getting back to the thing of selecting columns, no, I'm not talking about actual tables, like HTML ones: I just mean selecting a column of text in a text file. No delimiters, just text. It could be a table, or it could just be a block of text where you need to rearrange stuff, like, say, if you're converting C #defines to ASM EQUates. Stuff like that. Multi-Edit did it effortlessly. (The last time I needed something like that is when I downloaded some data from the US Navy, day-length data, and needed to turn their 2-D table into a 1-D list. Column-selection would have made it a piece of cake.
Multi-Edit also has really nice case-changing ops: set upper- or lowercase, capitalize first letter, etc. I miss it.
-
Okay, I think I know what you mean now. Similarly the way you can select text in a command window in quick edit mode. I think the font has to be a mono space font for that to work. I don't know exactly how to code for that, but it uses some gdi functions to select a rectangle around the text and some other functions to determine font width height, etc.
When you said the word 'table' I was thinking a data structure type table. You want to 'rubber band' select text in a rectangle?
Im not sure if I have the coding mojo for that.
-
When you said the word 'table' I was thinking a data structure type table. You want to 'rubber band' select text in a rectangle?
Im not sure if I have the coding mojo for that.
Not sure if I do either, TBH. It's a bitch of a problem. But Multi-Edit did it, so I know it's possible.
Yes, would work best with a monospaced font.
-
I think I've got some ideas where to get more info on that. I think there is a useful example (in C) in win32.hlp of all places iirc. Unless I'm mistaken where I'd seen it.
Edit to add. I can't seem to find it there. I know it was a dated (Win 95-98 era) source where I'd seen the code though.
If all else fails, I could code something into a console window perhaps. That seems the most viable option. This way the internals of the console window would do the 'heavy lifting' so to speak.
-
Mmm, don't think that's the right approach here. Don't think in terms of "what Win32 functions/controls, etc. can I use?". This is a work-it-out-with-paper-and-pencil problem. Think of an array of characters (the text): how do you select a column of them? Once you've figured that out, then you can start fleshing out the details.
At least that's the way I'm approaching it.
-
It was a "last ditch" thought...
I'll tinker with this in my spare time.
-
Multi-Edit also has really nice case-changing ops: set upper- or lowercase, capitalize first letter, etc. I miss it.
So, why aren't you still using it? (Multi-Edit)
If you need an older version than the site offers, have you tried the Wayback Machine?
-
Just use Notepad++ it has column selection and editing, proper, upper and lower case conversion, lines sorting and other stuff.
-
So, why aren't you still using it? (Multi-Edit)
If you need an older version than the site offers, have you tried the Wayback Machine?
Ah, I see. It aint cheap. Even on the wayback machine (old old versions), and no way to download a trial version
So nevermind
-
Just use Notepad++ it has column selection and editing, proper, upper and lower case conversion, lines sorting and other stuff.
I just downloaded Notepad++ to see if it selects the way you want it to, NoCforMe.
Yes, indeed it does. Have to hold down the ALT key, make the selection release ALT key right click the selected text or use menu to copy. [SOLVED]
Thank you fearless :thumbsup: , saved me and NoCforMe countless hours of trying to code that type of function. :cool:
Example of column(vertical) text selection below
-
So, why aren't you still using it? (Multi-Edit)
As I said earlier, it no longer runs under (modern) Windows. I think it still works under W2K, but I no longer use that machine for editing.
Messing with the "compatibility" settings does no good.
-
Just use Notepad++ it has column selection and editing, proper, upper and lower case conversion, lines sorting and other stuff.
Where is Notepad++? Is it part of Masm32? I looked but couldn't find it.
-
Where is Notepad++?
direct link to Notepadd++ version 6.2.3.0 (for compatibility):
https://notepad-plus-plus.org/downloads/v6.2.3/
-
OK, got it. I'll play around with it.
-
OK, got it.
:thumbsup:
-
It's a bitch of a problem. But Multi-Edit did it, so I know it's possible.
Yes, would work best with a monospaced font.
- copy the block of text you want to edit
- launch the attached exe
- select the text of the first row according to your needs
- use the menu
-
I shall start posting all my code using cmp/jmp style coding :badgrin:
You laugh, but some of us (me) actually prefer the cmp/jxx style. Here's how I like to lay out my message dispatchers:
MOV EAX, uMsg
CMP EAX, WM_COMMAND
JE do_command
CMP EAX, WM_LBUTTONDOWN
JE do_lbuttondown
CMP EAX, WM_NOTIFY
JE do_notify
CMP EAX, WM_PAINT
JE do_paint
. . .
do_command:
MOV AX, WORD PTR wParam
CMP AX, IDOK
JE do_processing
CMP AX, IDCANCEL
JE do_close
. . .
do_lbuttondown:
; (big block of code here)
do_notify:
; (another big block o'code)
do_paint:
; (more big blox of code)
have you tried use SETZ/SETNZ/SETGE/SETLS reg/mem instead of J**?
sets 0(false) or 1(true) to destination reg/mem
simpler version of SIMD packed compares resulting in mask 0(FALSE) or (TRUE) FFh(bytes),FFFFh(words),FFFFFFFh(dwords) depending on size
-
lol.
After the first 3 posts in this thread, the discussion took a hard left. (Off on a tangent far from original topic)
Funny how threads take on a life of their own. I gave up, and joined in the madness.
@daydreamer:
cmp/j?? combinations have their place imo, but not preferred by many. Same with push/call syntax.
-
Same with push/call syntax.
[opinion ON] Push-push-call, in my view, is just plain demented. All pain, no gain. What's the advantage of it? It does exactly what INVOKE does, but in a much less clear way. Way to obfuscate your code. Don't use it. [opinion OFF]
-
Sometimes with multiple calls to the same function a register is used. That's when its kinda appropriate as well as other addressing schemes involving registers. The output would start resembling Delphi code at that stage. :tongue: invoke eax does'nt work. I've tried :toothy: But that style does have its uses, say for high performance functions without stack frame for instance. But other than with registers yes push/push/call is kinda lame.
-
What are you talking about? Something like this situation?
INVOKE SomeFunction, EBX, ESI, EDI
MOV ESI, somePtr
MOV EDI, someOtherPtr
INVOKE SomeFunction, EBX, ESI, EDI
How would push-push-call make this any clearer or more effective? The answer is it couldn't. Unless I'm missing something in your point ...
Registers or memory variables, makes no never-mind.
-
mov edi, dword ptr [esi+ebx*4]
push something
push somfinelse
call edi
later
push 0
push another
call edi
Not pushing registers but calling the address pointed to by a register. Have'nt you seen any delphi code? :skrewy:
-
OK, you're talking about indirect calling through a register. Very very useful technique. No, I'm not familiar with Delphi (don't really even know what it is), but I've used this technique myself. I have a program that has a long list of "properties" for an item. Each property has two small functions, one for getting the property, the other for setting it. The addresses of these little stub functions are in a structure. Here's the code for getting these properties, inside a loop in a function that fills the property list for an item:
LEA ESI, CtrlProps
; Add this property to listbox:
MOV EDX, ctrlPtr
CALL [ESI].$pr.getFunPtr ;Call "get data" function.
MOV propValue, EAX
. . .
ADD ESI, SIZEOF $pr ;Next property.
ESI points to a structure whose elements contain members which are pointers to functions (getFunPtr and setFunPtr). Each function expects a pointer to be passed in EDX and returns its value in EAX. Makes it really really easy to add properties without massively rewriting a lot of code. (Shows my preference for what I call "data-driven programming"; instead of further complicating your code with a lot of conditionals and junk, put everything into a data structure and use that for expansion. Works great.)
You're right about one thing: if those functions needed any parameters passed on the stack, you'd need to use push-push-call for them. Here everything is just passed through a couple registers.
And ackshooly, this example uses indirect calling through a memory variable, not a register, but same difference.
This thread is already totally distorted, so a little more won't hurt, will it?
-
No, it's indicated in the title, first three post - on topic, other stuff follows. :toothy:
It's got a life of its own now.
Yes, indirect call. I forgot what that is called. You really don't want to see disassembled Delphi code. I think they make it that way for security against script kiddies fooling with the code.
-
Delphi has its origin from Pascal and is often referred to as Delphi Pascal.
Ugh. I hate it already.
Didn't realize it was a Borland product. Small claim to fame: A friend from back in the Beige Area used to work for Philippe Kahn.
-
A bloated software maker Delphi is. Iirc pascal wasn't so bad. But again, I've never programmed with either.
-
Fixed the code in the first post. And fixed the same code in the attachment in the third post. Sorry 'bout that, it was overlooked.