Author Topic: Need help with asembler (masm32) code  (Read 1003 times)

0 Members and 1 Guest are viewing this topic.

Aurel

  • Guest
Need help with asembler (masm32) code
« on: February 16, 2020, 12:18:56 am »
hello Charles
i need help with one small assembler code
if is not problem, i want translate it to o2
so can i post code here?

thanks

Aurel

  • Guest
Re: Need help with asembler (masm32) code
« Reply #1 on: February 16, 2020, 02:31:18 am »
one thing is not clear to me
what means  mov eax,pt.y ?
is that mean  eax = pt.y   or  something else
i simply cannot figured that assembly ... :-[

Charles Pegge

  • Admin Support Member
  • *****
  • Posts: 4486
    • Oxygen Basic
Re: Need help with asembler (masm32) code
« Reply #2 on: February 16, 2020, 04:34:20 am »
Hi Aurel,

Show us the assembler. It may be possible to do it entirely in o2 basic.

Aurel

  • Guest
Re: Need help with asembler (masm32) code
« Reply #3 on: February 16, 2020, 07:30:32 am »
Ok Charles , not problem at all
of course must be possible it is dialog app.. ;)
it is about line numbers in richedit control with margin
I have fight with this program whole day..and i become really pissed off
it simply drives me crazy this push eax,pop registers..gee  >:(
here is masm code:

Code: [Select]
include \masm32\include\masm32rt.inc

DlgRichEdit MACRO dstyle,tx,ty,wd,ht,ctlID
    align_4 edi
    mov DWORD PTR [edi+0],  WS_VISIBLE or WS_CHILD or dstyle
    mov WORD  PTR [edi+8],  tx
    mov WORD  PTR [edi+10], ty
    mov WORD  PTR [edi+12], wd
    mov WORD  PTR [edi+14], ht
    mov WORD  PTR [edi+16], ctlID
    add edi, 18
    ustring "RichEdit20A"
    align_2 edi
    add edi, 2
ENDM

IDC_EDIT    EQU 100
MARGIN_X    EQU 30

.data?
    g_hInstance     HINSTANCE ?
    g_pOrgWndProc   WNDPROC ?
.code
WndProc  proc uses esi edi ebx hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
LOCAL pt:POINT
LOCAL sz[16]:CHAR
LOCAL lc:DWORD
LOCAL rect:RECT,rgn:HRGN

    invoke CallWindowProc,g_pOrgWndProc,hWnd,uMsg,wParam,lParam
    .if uMsg == WM_PAINT
        push eax
        .if rvx(lc=SendMessage,hWnd,EM_GETLINECOUNT,0,0)
            fnx ebx = GetDC,hWnd

            fn SaveDC,ebx
            fn GetClientRect,hWnd,&rect
            fn SelectClipRgn,ebx,rvx(rgn = CreateRectRgn,rect.left,rect.top,rect.right,rect.bottom)
           
            ;fnx br = SelectObject,ebx,rv(CreateSolidBrush,bkColor)
            invoke BitBlt,ebx,0,0,MARGIN_X,rect.bottom, ebx,0,0,PATCOPY
            ;fn DeleteObject,rv(SelectObject,ebx,br)
           
            fnx esi=SendMessage,hWnd,EM_GETFIRSTVISIBLELINE,0,0
            .while esi <= lc
                .break .if rv(SendMessage,hWnd,EM_LINEINDEX,esi,0) == -1
                fn SendMessage,hWnd,EM_POSFROMCHAR,&pt,eax
                mov eax,pt.y
                .break .if SDWORD ptr eax > rect.bottom
                fn wsprintf,&sz,"%lu",&[esi+1]
                fn TextOut,ebx,0,pt.y,&sz,rv(lstrlen,&sz)
                add esi,1
            .endw
            fn RestoreDC,ebx,-1
            fn DeleteObject,rgn
            fn ReleaseDC,hWnd,ebx
        .endif
        pop eax
    .endif
    ret
   
WndProc endp

DlgProc proc uses esi edi ebx hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
LOCAL rect:RECT

    .if uMsg == WM_INITDIALOG
        invoke SendDlgItemMessage,hWnd,IDC_EDIT,EM_SETMARGINS,EC_LEFTMARGIN,MARGIN_X
        fnx g_pOrgWndProc = SetWindowLong,rv(GetDlgItem,hWnd,IDC_EDIT),GWL_WNDPROC,WndProc
        xor eax,eax
    .elseif uMsg == WM_CLOSE
        fn EndDialog,hWnd,0
    .else
        xor eax,eax
    .endif
    ret
   
DlgProc endp

main proc
   
    fnx g_hInstance = GetModuleHandle,0
    fn LoadLibrary,"Riched20.dll"
   
    Dialog "test","MS Sans Serif",12,WS_OVERLAPPED or WS_SYSMENU or DS_CENTER,1,10,10,100,100,1024
    DlgRichEdit ES_MULTILINE or ES_WANTRETURN or ES_AUTOHSCROLL or ES_AUTOVSCROLL ,0,0,90,50,IDC_EDIT
    CallModalDialog g_hInstance,0,DlgProc,0
   
    exit
main endp
end main

Aurel

  • Guest
Re: Need help with asembler (masm32) code
« Reply #4 on: February 16, 2020, 09:22:19 am »
Charles
I think that this should work without subclassing but this while loop
is too tricky to me.

Aurel

  • Guest
Re: Need help with asembler (masm32) code
« Reply #5 on: February 16, 2020, 10:54:48 am »
Just to let you know i get this ..but not work exactly as it should...
Code: [Select]
SUB drawLineNumber( int redit)
 int fv,lc,rv,rgn,lch=0,lnum=0,c
'POINTAPI pt

 int hdc = GetDC(redit )
     /*get height of rich edit so that the height of the rich edit control can be calculated*/
 SaveDC(hdc)
   
     'get height of font being used
 
        TEXTMETRIC tm
        GetTextMetrics( hdc, tm )
        int fontH = tm.tmHeight       

RECT rc
GetClientRect (redit, rc)
rc.right = leftM - 8
rgn = CreateRectRgn(rc.left,rc.top,rc.right,rc.bottom)
SelectClipRgn (hdc,rgn)
       
        'int hBr = CreateSolidBrush(rgb(220,216,207))
FillRect (hDC, rc,GetStockObject( WHITE_BRUSH))
SetBkMode (hDC, TRANSPARENT)
SetTextColor (hDC,rgb(92,92,220))

      'pos=0
      'get line count
       lc = SendMessage (redit,EM_GETLINECOUNT,0,0) : SetText(edit2,str lc)
      'get the first visible line     
      fv = SendMessage(redit, EM_GETFIRSTVISIBLELINE, 0, 0) ': SetText edit4, str(fv)
   
'get the last character/line
        'POINTAPI pt
'pt.x = rc.left
'pt.y = rc.bottom

       
while c <= lc
      lch = SendMessage (redit,EM_LINEINDEX,fv+c,0,)
            if lch = -1 then exit while
      lnum = SendMessage (redit, EM_LINEFROMCHAR, lch, 0):SetText edit4, str(lnum)
       lnum = lnum + 1

POINTAPI pt
pt.x = rc.left
pt.y = rc.bottom
SendMessage (redit, EM_POSFROMCHAR, &pt , lch )
RECT trc
         trc.right = 55
trc.left = 0
trc.bottom = rc.bottom
trc.top = pt.y


       if pt.y > rc.bottom then exit while
         
'DrawText (hDc, Str(pt.y), 1, rc, DT_RIGHT)
TextOut hdc, 0 , pt.y , str(lnum), Len(str lnum)

         c++
UpdateWindow redit
wend
   

Charles Pegge

  • Admin Support Member
  • *****
  • Posts: 4486
    • Oxygen Basic
Re: Need help with asembler (masm32) code
« Reply #6 on: February 19, 2020, 02:46:22 am »
Hi Aurel,

This uses Roland's dialogs.inc to build a RichEdit modal dialog, and is translated into o2 basic

Very interesting - being able to overlay the RichEdit control with line numbers (and potentially other margin annotations)

Code: [Select]
'http://masm32.com/board/index.php?topic=3079.0
'http://www.jose.it-berater.org/richedit/iframe/index.htm
'http://forums.codeguru.com/showthread.php?446242-rich-edit-control-line-numbering-number
'https://groups.google.com/forum/#!topic/borland.public.cppbuilder.vcl.components.using/4cEJOqvXs0U

'include \masm32\include\masm32rt.inc
uses dialogs

'macro DlgRichEdit(dstyle,tx,ty,wd,ht,ctlID)
'    align_4 edi
'    mov DWORD PTR [edi+0],  WS_VISIBLE or WS_CHILD or dstyle
'    mov WORD  PTR [edi+8],  tx
'    mov WORD  PTR [edi+10], ty
'    mov WORD  PTR [edi+12], wd
'    mov WORD  PTR [edi+14], ht
'    mov WORD  PTR [edi+16], ctlID
'    add edi, 18
'    ustring "RichEdit20A"
'    align_2 edi
'    add edi, 2
'end macro

% IDC_EDIT 100
% IDC_RICHEDIT 101
% MARGIN_X  30

'.data?
    sys g_hInstance     'HINSTANCE ?
    sys g_pOrgWndProc   'WNDPROC ?
'.code
'WndProc  proc uses esi edi ebx hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
'
function WndProc(sys hWnd,UMsg,wParam,lParam) as int callback
=============================================================
POINT  pt
CHAR sz[16]
DWORD lc
RECT crect
sys rgn
int dret
sys hDC
int line
int charpos

    dret=CallWindowProc(g_pOrgWndProc,hWnd,uMsg,wParam,lParam)

    if uMsg == WM_PAINT
        lc=SendMessage(hWnd,EM_GETLINECOUNT,0,0)
        if lc
            hDC = GetDC(hWnd)
            SaveDC(hDC)
            GetClientRect(hWnd,&crect)
            rgn = CreateRectRgn(crect.left,crect.top,crect.right,crect.bottom)
            SelectClipRgn(hDC,rgn)
           
            ;fnx br = SelectObject,ebx,rv(CreateSolidBrush,bkColor)
            % PATCOPY 0x00F00021
            BitBlt(hDC,0,0,MARGIN_X,crect.bottom, hDC,0,0,PATCOPY)
            ;fn DeleteObject,rv(SelectObject,ebx,br)
           
            line=SendMessage(hWnd,EM_GETFIRSTVISIBLELINE,0,0)
            while line <= lc
                charpos = SendMessage(hWnd,EM_LINEINDEX,line,0)
                exit if charpos == -1
                SendMessage(hWnd,EM_POSFROMCHAR,&pt,charpos)
                exit if pt.y > crect.bottom
                'wide char
                wsprintf(&sz,"%lu",line+1)
                TextOut(hDC,0,pt.y,sz,len(sz))
                line++
            wend
            RestoreDC(hDC,-1)
            DeleteObject(rgn)
            ReleaseDC(hWnd,hDC)
        endif     
    endif
    return dret
end function 'wndproc


'DlgProc proc uses esi edi ebx hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
function DlgProc(sys hWnd,uMsg,wParam,lParam) as int callback
=============================================================
Rect crect

    if uMsg == WM_INITDIALOG
         % EC_LEFTMARGIN 1
         SendDlgItemMessage(hWnd,IDC_EDIT,EM_SETMARGINS,EC_LEFTMARGIN,MARGIN_X)
        g_pOrgWndProc = SetWindowLong(GetDlgItem(hWnd,IDC_EDIT),GWL_WNDPROC,@WndProc)
        return 0
    elseif uMsg == WM_CLOSE
        return EndDialog(hWnd,0)
    else
        return 0
    endif
end function 'DlgProc endp

'main proc
   
    g_hInstance = GetModuleHandle(0)
    LoadLibrary("Riched20.dll")
   init_common_controls
   
   sys hDlg

   Dialog( 0, 0, 200, 100, "RichEdit modal dialog with line numbers",
                WS_OVERLAPPEDWINDOW or DS_CENTER )
   RichEdit( "RichEdit"+chr(13)+"box", IDC_EDIT, 0, 0, 200, 100, ES_AUTOHSCROLL or WS_HSCROLL )
   hDlg = CreateModalDialog( null, @DlgProc, 0 )
   
    'Dialog "test","MS Sans Serif",12,WS_OVERLAPPED or WS_SYSMENU or DS_CENTER,1,10,10,100,100,1024)
    'DlgRichEdit(ES_MULTILINE or ES_WANTRETURN or ES_AUTOHSCROLL or ES_AUTOVSCROLL ,0,0,90,50,IDC_EDIT)
    'CallModalDialog(g_hInstance,0,@DlgProc,0)

   
'exit
'main endp
'end main

Aurel

  • Guest
Re: Need help with asembler (masm32) code
« Reply #7 on: February 19, 2020, 03:58:45 am »
Hi Charles

And thank you very much on this translation.
I found last day few more strange eamples but in c# and in some other half-baked examples.

Just one question:
Is that program use subclassing method?
And yes i found one in C or C++, called RichEditor50W ...which use different richedit50W class control
which have markers and some other stuff including syntax coloring..program is very complex and large.
Ok i am going to compile this one...  ;)
« Last Edit: February 19, 2020, 05:44:32 am by Aurel »

Aurel

  • Guest
Re: Need help with asembler (masm32) code
« Reply #8 on: February 19, 2020, 05:39:38 am »
Hi Charles
work excellent  :D

I see now where i make mistakes, it is about push/pop as i expect,
I simply forget to use IF  ::)
and i don't know that we have in o2 EXIT IF ...
probably because i never use it.
I will try to addapt this code to one of my programs with more colors.
all best  ;)

Charles Pegge

  • Admin Support Member
  • *****
  • Posts: 4486
    • Oxygen Basic
Re: Need help with asembler (masm32) code
« Reply #9 on: February 20, 2020, 08:12:08 am »
I suppose it is a form of subclassing. The RichEdit control messages are intercepted by a customised wndproc. This should not be confused with a main wndproc. It would be clearer to call it something like EdProc to avoid confusion.

Aurel

  • Guest
Re: Need help with asembler (masm32) code
« Reply #10 on: February 20, 2020, 08:28:11 am »
Yes Charles
I am working on that ..
it looks that :

 SetWindowLong(GetDlgItem(hWnd,IDC_EDIT),GWL_WNDPROC,@WndProc)

not repond on created control in Window ...as it says GetDialogitem
so not return any value, i checked it with print()

EDIT: Charles ..i find that my SetWindowLong is wrong so i made new declaration and finally get returned value!
« Last Edit: February 20, 2020, 08:58:31 am by Aurel »