memory read forbidden helpppppp (cause of my browser,it post lots of timessorry)

Started by xiahan, March 31, 2012, 03:11:17 PM

Previous topic - Next topic

xiahan

; #########################################################################
;
; The framing affects are drawn on the client area by a single procedure,
; "Frame3D". In the WmdProc message handling Proc, the WM_PAINT message
; calls another Proc called "Paint_Proc" which contains the procedure calls
; to "Frame3D".
;
; #########################################################################

      .386
      .model flat, stdcall
      option casemap :none   ; case sensitive

; #########################################################################

      include \masm32\include\windows.inc
      include \masm32\include\user32.inc
      include \masm32\include\kernel32.inc
      include \masm32\include\gdi32.inc
     
      includelib \masm32\lib\user32.lib
      includelib \masm32\lib\kernel32.lib
      includelib \masm32\lib\gdi32.lib

; #########################################################################

      ;=============
      ; Local macros
      ;=============

      szText MACRO Name, Text:VARARG
        LOCAL lbl
          jmp lbl
            Name db Text,0
          lbl:
        ENDM

      m2m MACRO M1, M2
        push M2
        pop  M1
      ENDM

      return MACRO arg
        mov eax, arg
        ret
      ENDM

        ;=================
        ; Local prototypes
        ;=================
        WinMain PROTO :DWORD,:DWORD,:DWORD,:DWORD
        WndProc PROTO :DWORD,:DWORD,:DWORD,:DWORD
        TopXY PROTO   :DWORD,:DWORD
        Paint_Proc PROTO :DWORD, hDC:DWORD
        Frame3D PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD
        PushButton PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD

    .data
        szDisplayName db "3D Frames",0
        CommandLine   dd 0
        hWnd          dd 0
        hInstance     dd 0

    .code

start:
        invoke GetModuleHandle, NULL
        mov hInstance, eax

        invoke GetCommandLine
        mov CommandLine, eax

        invoke WinMain,hInstance,NULL,CommandLine,SW_SHOWDEFAULT
        invoke ExitProcess,eax

; #########################################################################

WinMain proc hInst     :DWORD,
             hPrevInst :DWORD,
             CmdLine   :DWORD,
             CmdShow   :DWORD

        ;====================
        ; Put LOCALs on stack
        ;====================

        LOCAL wc   :WNDCLASSEX
        LOCAL msg  :MSG

        LOCAL Wwd  :DWORD
        LOCAL Wht  :DWORD
        LOCAL Wtx  :DWORD
        LOCAL Wty  :DWORD

        ;==================================================
        ; Fill WNDCLASSEX structure with required variables
        ;==================================================

        mov wc.cbSize,         sizeof WNDCLASSEX
        mov wc.style,          CS_HREDRAW or CS_VREDRAW \
                               or CS_BYTEALIGNWINDOW
        mov wc.lpfnWndProc,    offset WndProc
        mov wc.cbClsExtra,     NULL
        mov wc.cbWndExtra,     NULL
        m2m wc.hInstance,      hInst   ;<< NOTE: macro not mnemonic
        mov wc.hbrBackground,  COLOR_BTNFACE+1
        mov wc.lpszMenuName,   NULL
        mov wc.lpszClassName,  offset szClassName
          invoke LoadIcon,hInst,500    ; icon ID
        mov wc.hIcon,          eax
          invoke LoadCursor,NULL,IDC_ARROW
        mov wc.hCursor,        eax
        mov wc.hIconSm,        0

        invoke RegisterClassEx, ADDR wc

        ;================================
        ; Centre window at following size
        ;================================

        mov Wwd, 500
        mov Wht, 350

        invoke GetSystemMetrics,SM_CXSCREEN
        invoke TopXY,Wwd,eax
        mov Wtx, eax

        invoke GetSystemMetrics,SM_CYSCREEN
        invoke TopXY,Wht,eax
        mov Wty, eax

        szText szClassName,"Template_Class"

        invoke CreateWindowEx,WS_EX_LEFT,
                              ADDR szClassName,
                              ADDR szDisplayName,
                              WS_OVERLAPPEDWINDOW,
                              Wtx,Wty,Wwd,Wht,
                              NULL,NULL,
                              hInst,NULL
        mov   hWnd,eax

        invoke LoadMenu,hInst,600  ; menu ID
        invoke SetMenu,hWnd,eax

        invoke ShowWindow,hWnd,SW_SHOWNORMAL
        invoke UpdateWindow,hWnd

      ;===================================
      ; Loop until PostQuitMessage is sent
      ;===================================

    StartLoop:
      invoke GetMessage,ADDR msg,NULL,0,0
      cmp eax, 0
      je ExitLoop
      invoke TranslateMessage, ADDR msg
      invoke DispatchMessage,  ADDR msg
      jmp StartLoop
    ExitLoop:

      return msg.wParam

WinMain endp

; #########################################################################

WndProc proc hWin   :DWORD,
             uMsg   :DWORD,
             wParam :DWORD,
             lParam :DWORD

        LOCAL hDC  :DWORD
        LOCAL Ps   :PAINTSTRUCT


    .if uMsg == WM_COMMAND
    ;======== menu commands ========
        .if wParam == 1000
            invoke SendMessage,hWin,WM_SYSCOMMAND,SC_CLOSE,NULL
        .elseif wParam == 1900
            szText TheMsg,"Assembler, Pure & Simple"
            invoke MessageBox,hWin,ADDR TheMsg,ADDR szDisplayName,MB_OK
        .endif
    ;====== end menu commands ======

    .elseif uMsg == WM_PAINT
        invoke BeginPaint,hWin,ADDR Ps
          mov hDC, eax
          invoke Paint_Proc,hWin,hDC
        invoke EndPaint,hWin,ADDR Ps
        return 0



       


    .elseif uMsg == WM_CLOSE
        szText TheText,"Please Confirm Exit"
        invoke MessageBox,hWin,ADDR TheText,ADDR szDisplayName,MB_YESNO
          .if eax == IDNO
            return 0
          .endif
    .elseif uMsg == WM_DESTROY
        invoke PostQuitMessage,NULL
        return 0
    .endif

    invoke DefWindowProc,hWin,uMsg,wParam,lParam

    ret

WndProc endp

; ########################################################################

TopXY proc wDim:DWORD, sDim:DWORD

    shr sDim, 1      ; divide screen dimension by 2
    shr wDim, 1      ; divide window dimension by 2
    mov eax, wDim    ; copy window dimension into eax
    sub sDim, eax    ; sub half win dimension from half screen dimension

    return sDim

TopXY endp

; #########################################################################

Paint_Proc proc hWin:DWORD, hDC:DWORD

    LOCAL crChain[256]   :DWORD
    LOCAL cy  :BYTE
    LOCAL hOldPen :DWORD
    LOCAL hPen  :DWORD

    lea esi,crChain
    push esi 
    mov ecx,0
    .while ecx < 31
      invoke GetSysColor,ecx
      mov [esi], eax
      add esi,4
      add ecx,1
   .endw 
   pop esi
   invoke CreatePen,5,1,0FFFFFFh
   mov hPen,eax
   invoke SelectObject,hDC,hPen
   mov hOldPen,eax
     
   push hOldPen
   mov ecx,32
   mov cy,1
   .while ecx > 0
       invoke CreatePen,0,1,[esi]
       mov hPen,eax
       invoke SelectObject,hDC,hPen
       mov hOldPen,eax
       invoke DeleteObject,hOldPen       
       invoke MoveToEx,hDC,1,cy,NULL
       invoke LineTo,hDC,498,cy
       add cy,2
       add esi,4
       dec ecx
   .endw 
   invoke DeleteObject,hPen
   pop hOldPen
   invoke SelectObject,hDC,hOldPen
   ret

Paint_Proc endp

;##########################################################################
end start
this is the whole code.
it's a 3dframes example program lies in C:\masm32\examples\exampl01\3dframes.
but i find the right most 3dframe has only one pixel width .
i search the weband find out the reason is that the Paint_Proc draws out of the client area
and i made some changes to it.now it can draw correctly.
have done above. i find the BUTTTON has three kinds of color,
the COLOR_BTNHIGHLIGHT AND COLOR_BTN SHADOW(already known) ,
and there's one unkown color i don't what it is.
so i want to iterate the SysColor to find out its value.   

dedndave

please - post your code with copy/paste, then use code tags (the # icon above the reply window)
and, of course, post it in one thread, only   :bg

    .while ecx > 0
you did not initialize ECX   :P

the cy stuff makes no sense
you probably meant to initialize cy to 1 outside the loop

you do not preserve ESI for the whole routine - that may not be a problem, if it is preserved in WndProc

don't feel bad, when i started programming for windows, i was gonna change my nic to c0000005 - lol

xiahan

sorry for the inappropriate posts .  :red
mov ecx,0
    .while ecx < 30

but the ecx grows into 29 and .while ecx > 0

what do you mean by "initialize ECX"

dedndave

the contents of ECX are destroyed when you make API calls
so - it may be 0 at the beginning of the second loop

also, ECX "grows" to 31 before the first loop exits

there are 31 indexes for system colors (0 to 30)
but, you use 0 to 29, so....
    mov     ecx,29
    .while ecx > 0

MichaelW

xiahan,

To test your code we need to be able to copy it as text and paste it into an editor, so it needs to be posted as text.
eschew obfuscation

xiahan


Paint_Proc proc hWin:DWORD, hDC:DWORD

    LOCAL crChain[256]   :DWORD
    LOCAL cy  :BYTE
    LOCAL hOldPen :DWORD
    LOCAL hPen  :DWORD

    lea esi,crChain
    push esi 
    mov ecx,0
    .while ecx < 30
      invoke GetSysColor,ecx
      mov [esi], eax
      add esi,4
      add ecx,1
   .endw 
   pop esi
   invoke CreatePen,5,1,0FFFFFFh
   mov hPen,eax
   invoke SelectObject,hDC,hPen
   mov hOldPen,eax
     
   push hOldPen
   mov ecx,30
   .while ecx > 0
       invoke CreatePen,0,1,[esi]
       mov hPen,eax
       invoke SelectObject,hDC,hPen
       mov hOldPen,eax
       invoke DeleteObject,hOldPen
       mov cy,1
       invoke MoveToEx,hDC,1,cy,NULL
       invoke LineTo,hDC,498,cy
       add cy,2
       add esi,4
       dec ecx
   .endw 
   pop hOldPen
   invoke SelectObject,hDC,hOldPen
   ret

Paint_Proc endp
this is the origin code .i alter the value of ECX before the second loop ,but the problem persist

dedndave

try this...
Paint_Proc proc USES EBX ESI hWin:DWORD, hDC:DWORD    ;notice that hWin is not used

    mov     esi,31
    mov     ebx,1
    .while esi>0
        mov     eax,31
        sub     eax,esi
        INVOKE  GetSysColor,eax
        INVOKE  CreatePen,PS_SOLID,1,eax
        INVOKE  SelectObject,hDC,eax
        .if esi==31
            push    eax                               ;hOrigPen on stack
        .else
            INVOKE  DeleteObject,eax
        .endif
        INVOKE  MoveToEx,hDC,1,ebx,NULL
        INVOKE  LineTo,hDC,498,ebx
        add     ebx,2
        dec     esi
   .endw

    pop     eax                                       ;EAX = hOrigPen
    INVOKE  SelectObject,hDC,eax
    INVOKE  DeleteObject,eax
    ret

Paint_Proc endp

qWord

maybe this one ...
; edi, ebx and esi must be preserved - Intel/WinABI
Paint_Proc proc uses edi esi ebx hWin:DWORD, hDC:DWORD

    LOCAL crChain[256]   :DWORD
    LOCAL cy  :BYTE
    LOCAL hOldPen :DWORD
    LOCAL hPen  :DWORD

    lea esi,crChain
    mov ebx,0
    .while ebx < 30
      invoke GetSysColor,ebx
      mov [esi], eax
      add esi,4
      add ebx,1
   .endw 

   lea esi,crChain
    mov cy,1   
   mov ebx,30
   .while ebx > 0
       invoke CreatePen,0,5,[esi]
       invoke SelectObject,hDC,eax
       mov hOldPen,eax
       invoke MoveToEx,hDC,0,cy,NULL
       invoke LineTo,hDC,498,cy
       invoke SelectObject,hDC,hOldPen
       invoke DeleteObject,eax
       add cy,5
       add esi,4
       dec ebx
   .endw 

   ret

Paint_Proc endp
FPU in a trice: SmplMath
It's that simple!

dedndave

slight update...
Paint_Proc proc USES EBX ESI hWin:DWORD, hDC:DWORD    ;notice that hWin is not used

    xor     esi,esi
    mov     ebx,1
    .while esi<31
        INVOKE  GetSysColor,esi
        INVOKE  CreatePen,PS_SOLID,1,eax
        INVOKE  SelectObject,hDC,eax
        .if esi==0
            push    eax                               ;hOrigPen on stack
        .else
            INVOKE  DeleteObject,eax
        .endif
        INVOKE  MoveToEx,hDC,1,ebx,NULL
        INVOKE  LineTo,hDC,498,ebx
        add     ebx,2
        inc     esi
   .endw

    pop     eax                                       ;EAX = hOrigPen
    INVOKE  SelectObject,hDC,eax
    INVOKE  DeleteObject,eax
    ret

Paint_Proc endp


i usually like qWord's code better than mine - lol
but, not this time   :bg

EDIT: notice that my code creates one more line than yours
there are 31 indexes to GetSysColor (0 to 30)
your code only did 30

dedndave

ok - last one   :P
i eliminated the hWin parm and made my own prologue/epilogue

Paint_Proc  PROTO :DWORD

;   INVOKE  Paint_Proc,hDC

;***********************************************************************

        OPTION  PROLOGUE:None
        OPTION  EPILOGUE:None

Paint_Proc PROC    hDC:DWORD

    push    ebx
    push    esi
    push    edi
    mov     ebx,[esp+16]                              ;EBX = hDC
    xor     esi,esi                                   ;ESI = color index/count
    mov     edi,1                                     ;EDI = Y position

    .while esi<31
        INVOKE  GetSysColor,esi
        INVOKE  CreatePen,PS_SOLID,1,eax
        INVOKE  SelectObject,ebx,eax
        .if esi==0
            push    eax                               ;hOrigPen on stack
        .else
            INVOKE  DeleteObject,eax
        .endif
        INVOKE  MoveToEx,ebx,1,edi,NULL
        INVOKE  LineTo,ebx,498,edi
        add     edi,2
        inc     esi
    .endw

    pop     eax                                       ;EAX = hOrigPen
    INVOKE  SelectObject,ebx,eax
    INVOKE  DeleteObject,eax
    pop     edi
    pop     esi
    pop     ebx
    ret     4

Paint_Proc ENDP

        OPTION  PROLOGUE:PrologueDef
        OPTION  EPILOGUE:EpilogueDef

;***********************************************************************

xiahan

thank you dedndave and qWord,your solution are both excellent :clap: I get the color i want .its index is 21 COLOR_3DDKSHADOW

and this is all what i talk about