News:

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

Main Menu

Holey Window

Started by jimg, November 20, 2024, 05:29:25 AM

Previous topic - Next topic

jimg

The program listed below is the start of my current project.  It is a simple program, it has a simple opaque window with two transparent and click-through rectangles on it.  The problem is that when I first run the program and move the cursor into the window area, I get the spinning circle busy cursor.  If I move out of the window, and wait a few seconds before moving back into the window, the cursor is okay.

I'm sure I'm having a senior moment and forgetting some simple windows must do somewhere, but I can't seem to find it.

If someone can see what message I need to service to avoid this problem, please let me know.


This is the stripped down code.  The window has no title bar, so just press a key to exit.


.686
.model flat, stdcall
option casemap:none

include windows.inc
include kernel32.inc
include user32.inc
include gdi32.inc

includelib kernel32.lib
includelib user32.lib
includelib gdi32.lib

inv equ INVOKE

.data
    ClassName db "WindowHoleClass", 0
    WindowName db "Window with click-through Rectangles", 0

    rect1 RECT <50, 50, 150, 150>   ; First rectangle (x1, y1, x2, y2)
    rect2 RECT <200, 100, 300, 200> ; Second rectangle (x1, y1, x2, y2)
    wc WNDCLASS <CS_HREDRAW or CS_VREDRAW,
           offset WndProc,0,0,0,0,0,,0,offset ClassName>
    backcolor dd 0f0f0fh  ; background (view blocking) color
    transparentcolor dd 020202h  ; must be different than backcolor
.data?
    msgx MSG <>
    ps PAINTSTRUCT <>
    hbBrush dd ?  ; background brush
    htBrush dd ?  ; transparent brush
    hdc dd ?      ; device construct
    hwnd dd ?
    hinst dd ?
.code

WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
    .if uMsg == WM_PAINT
        ; Begin painting
        inv BeginPaint, hWnd, addr ps
        mov hdc, eax

        ; Clear the background
        inv FillRect, hdc, addr ps.rcPaint, hbBrush

        ; Draw the transparent rectangles
        inv SelectObject, hdc, htBrush
        inv Rectangle, hdc, rect1.left,rect1.top,rect1.right,rect1.bottom
        inv Rectangle, hdc, rect2.left,rect2.top,rect2.right,rect2.bottom

        inv EndPaint, hWnd, addr ps

    .elseif uMsg== WM_KEYDOWN
        inv PostQuitMessage,0
    .elseif uMsg == WM_DESTROY
        inv PostQuitMessage,0
    .else
        inv DefWindowProc,hWnd,uMsg,wParam,lParam
        ret
    .endif
    xor eax, eax
    ret
WndProc endp

Program:
    inv GetModuleHandle, 0  ;get the instance handle
    mov hinst,eax
    ; Register window class
    mov wc.hInstance,eax
    inv RegisterClass, addr wc
    ; Create window
    inv CreateWindowEx, WS_EX_LAYERED,
         offset ClassName, offset WindowName,
         WS_POPUP or WS_VISIBLE or WS_BORDER,
         100, 100, 500, 300, 0, 0, hinst, 0
    mov hwnd, eax ; save window handle

    ; Set transparency color for drawing rectangles
    inv SetLayeredWindowAttributes,hwnd,transparentcolor,0,LWA_COLORKEY

    inv CreateSolidBrush, backcolor
    mov hbBrush, eax
    inv CreateSolidBrush, transparentcolor
    mov htBrush, eax

    ; Message loop
.repeat
        inv GetMessage, addr msgx, 0, 0, 0
        .break .if !eax
        inv TranslateMessage, addr msgx
        inv DispatchMessage, addr msgx
.until 0
    inv DeleteObject, hbBrush ; cleanup
    inv DeleteObject, htBrush ; cleanup
mov eax, msgx.wParam
    inv ExitProcess, 0
end Program

zedd151

Holy Holey windows, Batman!  :tongue:

It seems to work okay, but...
Sometimes the cursor would change to the 'busy' cursor while over the window as you had mentioned, but not always.

Otherwise I have tested the intended functionality and it works.
Running in ollydbg, I can click on things in ollys window. (inside the 'holes')
On the desktop, I can rearrange icons under the program window (inside the 'holes'.)  :thup:

Try SetCursor??
I have seen this before in some of my own programs.

invoke LoadCursor, NULL, IDC_ARROW
invoke SetCursor, eax

In testing, I placed that code just after window creation code (Next line after "mov hwnd, eax").
Ventanas diez es el mejor.  :azn:

sinsi

It's always a good idea to give your WNDCLASS a cursor and icon  :badgrin:
🍺🍺🍺

jimg

That was it sinsi, Thanks!

insert

    inv LoadCursor, 0, IDC_ARROW  ; important
    mov wc.hCursor,eax
before RegisterClass and everything is good.

The busy indicator must have been windows thinking about what to use :)

zedd151

#4
Quote from: sinsi on November 20, 2024, 07:50:52 AMIt's always a good idea to give your WNDCLASS a cursor and icon
It happens, and all too often, where that detail is forgotten. :biggrin:
Ventanas diez es el mejor.  :azn:

NoCforMe

Quote from: jimg on November 20, 2024, 08:05:41 AMThat was it sinsi, Thanks!

insert

    inv LoadCursor, 0, IDC_ARROW  ; important
    mov wc.hCursor,eax
before RegisterClass and everything is good.

The busy indicator must have been windows thinking about what to use :)

Wow; I think y'all just solved a problem of long standing that a lot of my programs have, showing a busy/waiting cursor for no good reason. Thanks!

And I totally believe your last sentence there explains why this happens.
Assembly language programming should be fun. That's why I do it.

sinsi

Quote from: jimg on November 20, 2024, 08:05:41 AMThe busy indicator must have been windows thinking about what to use :)
More like waiting for you to pick one :biggrin:
🍺🍺🍺

NoCforMe

Wait a sec: now I'm not so sure about this.

Why would not having a default cursor defined for a window cause the busy cursor to appear? Wouldn't it default to the regular old arrow? Or would registering the class with a NULL cursor cause Windows to show busy when you don't set a cursor like it's expecting you to? (Which tells me that in that case the busy cursor IS the default cursor.)

What else could cause the busy cursor? Could it be that no window is currently selected, or activated, or whatever? Does the cursor change if you click on the window to select it?

Of course the fact that setting a default cursor for the window class made the busy cursor go away does point to that being the cause of the problem, but is that really the case?
Assembly language programming should be fun. That's why I do it.

HSE

QuoteTipo: HCURSOR

Identificador del cursor de clase. Este miembro debe ser un identificador para un recurso de cursor. Si este miembro es NULL, una aplicación debe establecer explícitamente la forma del cursor cada vez que el mouse se mueve a la ventana de la aplicación.
Equations in Assembly: SmplMath

NoCforMe

En inglese, por favor:

QuoteClass cursor identifier. This member must be an identifier for a cursor resource. If this member is NULL, an application must explicitly set the shape of the cursor each time the mouse is moved to the application window.
Assembly language programming should be fun. That's why I do it.