News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Win32 My First Window

Started by tda0626, April 24, 2024, 11:05:19 AM

Previous topic - Next topic

NoCforMe

I'll let the OP answer this question, thanks.
Assembly language programming should be fun. That's why I do it.

tda0626

Quote from: sudoku on May 04, 2024, 05:02:13 AM
Quote from: NoCforMe on May 04, 2024, 04:12:29 AMI'll be happy to take a look at it.
I am fairly certain (75%) it is the code where TimoVJL's link points to. ( if you are refering to his 'converted' code) Thats why I posted that link above. #114

Quote from: TimoVJL on May 02, 2024, 06:41:12 PMMany of us remember this, from Petzold book:
HelloWin petzold-pw5e
Click the link and see...

Else there is a header file "SysMets.h" a bit further down that file tree there. (the "custom include file")???
 header file
That sounds to me like what he means by "Looked at his text metrics code and besides the custom include file he wants you to import into the program"

How would you do that include file to masm syntax?

zedd151

Quote from: NoCforMe on May 04, 2024, 05:53:37 AMI'll let the OP answer this question, thanks.
Well, you did invoke my name regarding his code...
Quote from: NoCforMe on May 03, 2024, 11:18:38 AMMore "refinement". Looking at Sudoku's converted code:
:smiley:  Just trying to lend a hand. And I was curious, so I looked through Timos link for myself... and thought that I would share what I found.

jj2007


NoCforMe

Quote from: tda0626 on May 04, 2024, 05:59:24 AMElse there is a header file "SysMets.h" a bit further down that file tree there. (the "custom include file")???
 header file
How would you do that include file to masm syntax?
If you're referring to SYSMETS.H, easy peasy. I'll actually do part of your homework here for you, since you'll end up having to do a shitload of typing anyhow.

All this file consists of is 1) a size equate (NUMLINES), 2) a structure definition (sysmetrics) and 3) a whole bunch of statements that fill in that structure.

First the equate:
#define NUMLINES ((int)(sizeof sysmetrics) / sizeof sysmetrics[0]))
This simply gives you the number of lines, which is the size of the entire structure divided by the size of one element. We'll deal with this in a bit, but first the structure definition:
struct
{
    int      iIndex;
    TCHAR *  szLabel;
    TCHAR *  szDesc;
}
easily translates to
SYSMETRIC_ENTRY    STRUCT
  iIndex      DD ?
  labelText   DD ?
  descText    DD ?
SYSMETRIC_ENTRY    ENDS
(I've given the structure itself a name, which wasn't needed in the original C program)

Now that you have the structure, defining the elements is easy. Except for one thing: in C, you can define the text that goes into the last 2 members AND put a pointer to them into the structure with the TEXT (C) macro.
As is well-known around here, I don't like using macros in assembly language, so the way I would do this is to first define all the strings, give them names, then put those names into the structure. This might seem a pain in the ass to you, so I'm going to be merciful and use the asm macro chr$ so you can put the text directly into the structure as in Petzold. Here are the first 2 elements of that structure:
SYSMETRIC_ENTRY <SM_CXSCREEN, chr$("SM_CXSCREEN"), chr$("Screen width in pixels")>
SYSMETRIC_ENTRY <SM_CYSCREEN, chr$("SM_CYSCREEN"), chr$("Screen height in pixels")>
That takes care of that structure; you just have to type in the rest of the entries.
BTW, @JJ: I hope I've used this macro correctly here. You can correct me if I've misused it.

Now to the matter of determining the number of "lines" (# of SYSMETRIC_ENTRY items):
While we can take the SIZEOF the structure in assembly language, there's no equivalent to the C operator "sizeof sysmetrics" which gives the size of the entire array of structures.

However, that's not difficult to do. What I would do is this:
sysmetrics    LABEL SYSMETRIC_ENTRY
SYSMETRIC_ENTRY <SM_CXSCREEN, chr$("SM_CXSCREEN"), chr$("Screen width in pixels")>
SYSMETRIC_ENTRY <SM_CYSCREEN, chr$("SM_CYSCREEN"), chr$("Screen height in pixels")>

    . . .
    . . .

$sysmetricsSize    EQU $ - sysmetrics    ;This is the size of the array of structs, in bytes.
and then make the size equate thus:
NUMLINES    EQU $sysmetricsSize / SIZEOF SYSMETRIC_ENTRY
BTW, another way to skin that cat, and the way that I prefer to do things, is to put a signal value at the end of the list, rather than calculating the number of items in the list and looping that number of times when displaying the list. Forget NUMLINES, and create the list thus:
SYSMETRIC_ENTRY <SM_CXSCREEN, chr$("SM_CXSCREEN"), chr$("Screen width in pixels")>
SYSMETRIC_ENTRY <SM_CYSCREEN, chr$("SM_CYSCREEN"), chr$("Screen height in pixels")>

    . . .
    . . .

      DD -1  ;STOP when iIndex = -1.
You'll have to modify his program to check for a -1 value in the first member of the structure (iIndex) to know when you've hit the end of the list. I'll leave it to you as an exercise if you want to go this way instead.

That's it.

Concerning the mechanics of actually converting this header file to assembly language, I realize it's not quite "easy peasy" because of all the typing and reformatting required. What you might want to do is to take the original .h file and reformat it in your editor; that way you have all the strings and constants you need. You just need to change this
    SM_CXSCREEN,          TEXT ("SM_CXSCREEN"),
                          TEXT ("Screen width in pixels"),
to this
SYSMETRIC_ENTRY <SM_CXSCREEN, chr$("SM_CXSCREEN"), chr$("Screen width in pixels")>
which isn't pleasant but not an impossible task either. Mostly a lot of copying and pasting.
Assembly language programming should be fun. That's why I do it.

tda0626

I modified it in Excel so check and see if it looks right. The inc file is attached.


Tim

NoCforMe

Wow. I'm impressed.
Never thought of using Excel; I use it occasionally, but am not an expert. Does it have more extensive search-and-replace capabilities than an editor?

Anyhow, looks OK. Let us know if it assembles correctly.
Assembly language programming should be fun. That's why I do it.

jj2007

Quote from: tda0626 on May 04, 2024, 08:44:35 AMI modified it in Excel

Three columns - clever :thumbsup:

Quote from: NoCforMe on May 04, 2024, 08:56:26 AMDoes it have more extensive search-and-replace capabilities than an editor?

Better than most editors ;-)

zedd151

Looks good :thumbsup:
I would have cooked up a qeditor plugin to handle the task.  :azn:

tda0626

Quote from: NoCforMe on May 04, 2024, 08:56:26 AMWow. I'm impressed.
Never thought of using Excel; I use it occasionally, but am not an expert. Does it have more extensive search-and-replace capabilities than an editor?

Anyhow, looks OK. Let us know if it assembles correctly.

Thanks!

When I imported the copy from the book to Excel, I used commas as a separator but it didn't quite work the way I wanted so I had to do some coping and pasting to line everything up and used the find and replace feature to get rid of unwanted words or characters in the cells and to get down to a base line look. Then I used the =trim formula to get rid of unwanted spaces. After that, I used =concat formula to add the extra characters before and after the strings.

tda0626

I am converting Charles Petzold's code over to assembly and I came across this

cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2) * cxChar / 2 ;

So what I think it does is this in my own way

.if tm.tmPitchAndFamily and 1
       
            shr cxChar, 1
            mov eax, cxChar
            test eax
            jz ODD
            add eax, cxChar
            mov cxCaps, eax
            ODD:
            add eax, cxChar
            sub eax,1
            mov cxCaps, eax
           
        .else
       
            mov eax, cxChar
            mov cxCaps, eax
           
        .endif

Is that close or somewhat right?


Tim

NoCforMe

Um, no, you've kinda got the cart before the horse there.
Let's parse that statement:
cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2) * cxChar / 2 ;
That says:
"cxCaps =
  (if (tm.tmPitchAndFamily AND 1) is non-zero--> 3
  else                                           2)
* cxChar / 2
You need to do the conditional test on tm.tmPitchAndFamily first (to get either 2 or 3), then multiply by cxChar / 2.

Hint: (something) / 2 = SHR  (something), 1.
Assembly language programming should be fun. That's why I do it.

tda0626

So if it is 2, then the statement is saying essentially multiply cxChar by 1 because shr 1 and then shl 1, so just need to multiply by 3 right?



.if tm.tmPitchAndFamily and 1 == 0

mov eax, cxChar
mov cxCaps, eax

.else

shr cxChar, 1
add eax, cxChar
sub eax,1
mov cxCaps, eax


tda0626

This has me hung up too.


TextOut (hdc, 0, cyChar * i, sysmetrics[i].szLabel,lstrlen (sysmetrics[i].szLabel)) ;

Not sure how to reference my structure like he is doing

sysmetrics[i].szLabel,

This is as far as I have gotten with it

invoke TextOutA, hdc, 0, cyChar * i,

NoCforMe

Well, you're not writing C here, so you can't use expressions like cyChar * i in an INVOKE statement. You'll need to do your address calculations before the call to TextOut().

Don't have the program code in front of me, so don't know where your index, i, is coming from, but let's assume it's in a variable called "index":
    LOCAL  y:DWORD

    MOV    EAX, index
    MUL    cyChar          ;i * cyChar
    MOV    y, EAX          ;Save the result (the y-position in the display)

; call some flavor of strlen() here, save its result in ECX

    MOV    EAX, SIZEOF SYSMETRIC_ENTRY
    MUL    index         
    ADD    EAX, OFFSET sysmetrics  ;EAX points to SYSMETRIC_ENTRY[index]
    MOV    EAX, [EAX].SYSMETRIC_ENTRY.labelText  ;EAX--> text to display

    INVOKE  TextOut, hdc, 0, y, EAX, ECX
I don't know what flavor of strlen() you'll be using (I have my own homegrown version), so you'll have to figure that part out. You'll probably have to put it after the address calculation and somehow preserve the results of the previous calculation (we're running out of registers here, so you might need a couple more local variables).

Note: keep in mind that MUL overwrites EDX (EAX x [something]--> EDX:EAX).

Hopefully you get the idea.
Assembly language programming should be fun. That's why I do it.