News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Listbox

Started by FlySky, August 11, 2009, 11:26:12 AM

Previous topic - Next topic

FlySky

Hey guys,

I am playing around with listboxes atm and created a simple dialog procedure on which my listbox is placed.
Than I want to use the SendMessage API to send strings to the listbox.

In 64 bit I am using this code:

InfoProc FRAME hwnd, uMsg, wParam, lParam

    push rsi
    push rdi

    mov rdi, [hwnd]
    invoke GetDlgItem,rdi,14
    mov rsi, rax
    mov rax, [uMsg]

    cmp D[uMsg],WM_CLOSE      
    jne >
    invoke EndDialog,rdi,0
    xor rax,rax
   
    :
   
    cmp D[uMsg],WM_INITDIALOG
    jne >>
        invoke  CreateFont,12,5,0,0,400,0,0,0,OEM_CHARSET, OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,DEFAULT_PITCH or FF_SCRIPT, addr Terminal             
        invoke SendMessage,rsi,WM_SETFONT,rax,0
        invoke RegisterHotKey,rdi,0,0,VK_ESCAPE

        mov     rdi,offset nfo
        xor     rbx,rbx
_lbloop:
        invoke  SendMessage,rsi,LB_INSERTSTRING,rbx,rdi
        Xor     rax,rax
_z01:   
         Scasb                                   
         Jnz<_z01             
         inc rbx
         cmp Q[rdi],0
         jnz<_lbloop       
         xor rax, rax

      :

      cmp  D[uMsg],WM_CTLCOLORLISTBOX
      jne >
            invoke SetBkMode,[wParam],TRANSPARENT  ; 1 = TRANSPARENT or 2 = OPAQUE
            invoke SetTextColor,[wParam],00ffffffh ; text color value
            invoke SetBkColor,[wParam],  00000000h ; Backgrn color value
            invoke CreateSolidBrush,   00000000h ; brush color value
            ret
      :

      cmp D[uMsg],WM_CTLCOLORDLG
      jne >   
      invoke  SetBkColor, [wParam], 00000000h
        invoke  GetStockObject, BLACK_BRUSH
      :

      cmp D[uMsg],WM_LBUTTONDOWN
      jne >
      invoke ReleaseCapture
      invoke SendMessage, rsi, WM_SYSCOMMAND, 0F012h, 0     
      :

      cmp D[uMsg],WM_RBUTTONDOWN
      jne >
      invoke SendMessage,rsi,EM_LINESCROLL,0,-9
     
      :

      pop rsi
      pop rdi
      xor rax,rax
      ret

ENDF

When compiling I get a black listbox with white text lines.
When changing the code to support 32 bit I am using the following code:

InfoProc FRAME hwnd, uMsg, wParam, lParam

    push esi
    push edi

    mov edi, [hwnd]
    invoke GetDlgItem,edi,14
    mov esi, eax
    mov eax, [uMsg]

    cmp D[uMsg],WM_CLOSE      
    jne >
    invoke EndDialog,edi,0
    xor eax,eax
   
    :
   
    cmp D[uMsg],WM_INITDIALOG
    jne >>
        invoke  CreateFont,12,5,0,0,400,0,0,0,OEM_CHARSET, OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,DEFAULT_PITCH or FF_SCRIPT, addr Terminal             
        invoke SendMessage,esi,WM_SETFONT,eax,0
        invoke RegisterHotKey,edi,0,0,VK_ESCAPE

        mov     edi,offset nfo
        xor     ebx,ebx
_lbloop:
        invoke  SendMessage,esi,LB_INSERTSTRING,ebx,edi
        Xor     eax,eax
_z01:   
         Scasb                                   
         Jnz<_z01             
         inc ebx
         cmp D[edi],0
         jnz<_lbloop       
         xor eax, eax

      :

      cmp  D[uMsg],WM_CTLCOLORLISTBOX
      jne >
            invoke SetBkMode,[wParam],TRANSPARENT  ; 1 = TRANSPARENT or 2 = OPAQUE
            invoke SetTextColor,[wParam],00ffffffh ; text color value
            invoke SetBkColor,[wParam],00000000h   ; Backgrn color value
            invoke CreateSolidBrush,00000000h ; brush color value
            ret
      :

      cmp D[uMsg],WM_CTLCOLORDLG
      jne >   
      invoke  SetBkColor, [wParam], 00000000h
        invoke  GetStockObject, BLACK_BRUSH
      :

      cmp D[uMsg],WM_LBUTTONDOWN
      jne >
      invoke ReleaseCapture
      invoke SendMessage, esi, WM_SYSCOMMAND, 0F012h, 0     
      :

      cmp D[uMsg],WM_RBUTTONDOWN
      jne >
      invoke SendMessage,esi,EM_LINESCROLL,0,-9
     
      :

      pop esi
      pop edi
      xor eax,eax
      ret

ENDF

The problem lies with the RET instruction at: cmp  D[uMsg],WM_CTLCOLORLISTBOX. When removing the ret instruction everything goes fine but I have an white background for the listbox. When placing the ret back it crashes as soon as I start. Maybe I am doing something wrong in goasm? as I converted the source from MASM. But the strange thing is on 64 bit it works fine, but doing the same thing on 32 bit as shown above it keeps crashing at that RET. I debugged it and as soon as that RET is hit, it jumps back to an adress 123?

This is the code I am using to call the dialogbox with the listbox on it:

   cmp D[uMsg],WM_COMMAND                                   
   jne >
   cmp D[wParam],2
   Invoke DialogBoxParam, [hInstance], 200, [hWin], addr InfoProc, 0
   xor eax, eax
   ret

Yuri

Maybe this is because you leave esi and edi on stack. Also, when you pop them at the last ret, you do it in the same order as you pushed them, which is wrong. I would recommend using the USES directive, it will pop the saved registers for you at any ret instruction.

InfoProc FRAME hwnd, uMsg, wParam, lParam
         USES edi, esi

FlySky

Yuri,

I am feeling pretty dumb here, your solution is working phenomenal. I kept overlooking the way I was pushing and poping EDI and ESI. Now that I used the USES directive all is working perfectly fine.
Thanks for your answer man.