I use ShowCursor(FALSE) to hide it and the reference count decreases respectively. It works very well, but I have an odd problem.
If I run my application by other means than double clicking the executable with my mouse, the cursor hides. But if I launch my program by double clicking it with my mouse the cursor never hides. There is nothing wrong with my mice, its a brand new mice in fact.
Why is that, could it be that the window loses focus in between the double click? I am catching and responding to both WM_SETCURSOR and WM_MOUSEMOVE but it doesnt solve the problem when I launch the app by double clicking the program icon.
If I select the program icon and press ENTER to launch it, the mouse cursor hides properly. :(
code says more than thousand words :wink:
Quoteinclude masm32rt.inc
.data?
hInstance HINSTANCE ?
.code
WndProc proto hWnd:HWND,uMgs:UINT,wParam:WPARAM,lParam:LPARAM
main proc
LOCAL wc:WNDCLASSEX
LOCAL msg:MSG
mov hInstance,rv(GetModuleHandle,0)
mov wc.hInstance,eax
mov wc.cbSize,SIZEOF wc
mov wc.style,CS_HREDRAW or CS_VREDRAW or CS_SAVEBITS
mov wc.lpfnWndProc,OFFSET WndProc
mov wc.cbClsExtra,0
mov wc.cbWndExtra,0
mov wc.hIcon,rv(LoadIcon,0,IDI_APPLICATION)
mov wc.hIconSm,eax
;/* no cursor */
mov wc.hCursor,0
mov wc.lpszMenuName,0
mov wc.hbrBackground,rv(GetStockObject,WHITE_BRUSH);
mov wc.lpszClassName,chr$("Win32Wnd")
invoke RegisterClassEx,ADDR wc
mov esi,rv(CreateWindowEx,0,wc.lpszClassName,"Win32Wnd",WS_VISIBLE or WS_SYSMENU or WS_MAXIMIZEBOX or WS_MINIMIZEBOX or WS_SIZEBOX,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,0,0,hInstance,0)
invoke UpdateWindow,esi
.while 1
invoke GetMessage,ADDR msg,0,0,0
.break .if !eax || eax == -1
invoke TranslateMessage,ADDR msg
invoke DispatchMessage,ADDR msg
.endw
invoke ExitProcess,0
main endp
WndProc proc hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
.if uMsg == WM_CLOSE
invoke PostQuitMessage,0
.elseif uMsg == WM_SETCURSOR
invoke SetCursor,0
mov eax,TRUE
ret
.else
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.endif
xor eax,eax
ret
WndProc endp
end main
Odd, I already have it like that. I have set wc.HCursor to null and i'm setting cursor in WM_SETCURSOR and returning TRUE as instructed by microsoft. I have also tried combining it with ShowCursor(FALSE)
Dont get me wrong, the thing works already, but it doesnt work if I launch my app using my mouse. Its an odd problem. If I run my app using my keyboard the cursor hides. :dazzled:
Could this have anything to do with my other threaded message dummy window?
You can solve your problem with a SetTimer call, but that doesn't solve the mystery...
Double-click is weird to begin with. You would assume that Windows simply logs the time and position of the first click then if another click occurs within a certain distance and time it treats it as a double click. In some cases this seems to be true but in others it isn't. I have tried to grasp the sequence of events that lead to a double click and have come up with very little. In my opinion, though I have no evidence to back it up, Windows captures the mouse after the first click and creates a waitable timer object, if the object expires there was no double click, if the button is pushed before expiration there was a double click. By capturing the mouse, Windows no long needs to worry about which window the mouse is over when the second click is received, simply that it is within the bounds specified in the system parameters. This could lead to some bizarre behavior if you're waiting for a mouse message between the two clicks, you will never get it because the mouse is captured by the system. Probably not much to do with your problem but one of my thought experiments, your problem has given me more data to refine my assumptions though, I'll let it bounce around in my head for a bit and maybe come up with an explanation.
I tried using a timer too, didnt work. It worked 30% of the time and failed the remaining 70%. I don't know why.
Ive set my window cursor to null before creating the window also. Some times when i run the program it shows a wait mouse icon, when the app shows a waiticon I know it will be hidden, it always hides when I see that, but when it shows a normal arrow icon, I know it will fail, it always does when it shows one.
I dont get it. The code is clean as toilet paper, I even feed the OS with hamburgers.
Anyways, it works more often when adding a timer, but it does not work all the times. In fact, this cant be the right way to go. There must be another more reliable way to do it. The question is what way to go when the ms docs says nothing about that.
I think the problem might be when switching from window to fullscreen mode. While this is happening it is possible the window loses focus because of the recent mouse click when I launched the application. I think this is the problem because when i press Enter to run it it works fine. It must be losing focus when i mouse click the program.
And so naturally I tried applying the focus back to the window by using SetForegroundWindow, no luck in doing that either.
My theory is that after it loses focus, ShowCursor(False) will fail because other apps or the desktop has the focus.
Why don't you send your source code? You can strip it to the essentials if you don't want to release your secrets ;-)
Here is the relevant of winmain:
;**********************************************************************************************
;-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_WINMAIN-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
;-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_WINMAIN-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
;-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_WINMAIN-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
;**********************************************************************************************
ALIGN 16
WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
LOCAL wc:WNDCLASSEX
LOCAL msg:MSG
LOCAL hwnd:HWND
LOCAL Color:DWORD
LOCAL ColChoice:DWORD
LOCAL D3D9_Interface:DWORD
LOCAL D3D9_Device:DWORD
LOCAL Quitting:DWORD
LOCAL D3D9_PresParam:D3DPRESENT_PARAMETERS
mov Quitting, 0
;**********************************************************************************************
;-_-_-winmain-_-_-_-_-_-_-_-_-_-_-_-_WINCLASS DATA-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
;**********************************************************************************************
mov wc.cbSize, SIZEOF WNDCLASSEX
mov wc.style, CS_OWNDC
mov wc.lpfnWndProc, OFFSET MainWndProc
mov wc.cbClsExtra, NULL
mov wc.cbWndExtra, NULL
push hInstance
pop wc.hInstance
mov wc.hbrBackground, COLOR_WINDOW+1
mov wc.lpszMenuName, NULL
mov wc.lpszClassName, OFFSET ClassName
Invoke LoadIcon,NULL,IDI_APPLICATION
mov wc.hIcon,eax
mov wc.hIconSm,eax
;Invoke LoadCursor,NULL,IDC_ARROW
mov wc.hCursor,NULL
;**********************************************************************************************
;-_-_-winmain-_-_-_-_-_-_-_-_-_-_-_-_REGISTER WINDOW-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
;**********************************************************************************************
Invoke RegisterClassEx, addr wc
;**********************************************************************************************
;-_-_-winmain-_-_-_-_-_-_-_-_-_-_-_-_CREATE WINDOW-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
;**********************************************************************************************
Invoke CreateWindowEx,WS_EX_TOPMOST,\
ADDR ClassName,\
ADDR AppName,\
WS_POPUP or WS_VISIBLE,\
CW_USEDEFAULT,\
CW_USEDEFAULT,\
WINDOW_WIDTH,\
WINDOW_HEIGHT,\
NULL,\
NULL,\
hInst,\
NULL
mov hwnd,eax
IF DEBUG EQ 1
mov DebugHwnd, eax
ENDIF
;**********************************************************************************************
;-_-_-winmain-_-_-_-_-_-_-_-_-_-_-_-_UPDATE WINDOW-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
;**********************************************************************************************
Invoke UpdateWindow, hwnd
;**********************************************************************************************
;-_-_-winmain-_-_-_-_-_-_-_-_-_-_-_-_CREATE DUMMY THREAD-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
;**********************************************************************************************
Invoke CreateThread, NULL, 0, OFFSET DummyWindowThread, 0, 0, NULL
mov DumTrHandle, eax
;**********************************************************************************************
;-_-_-winmain-_-_-_-_-_-_-_-_-_-_-_-_CREATE DX9 INTERFACE-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
;**********************************************************************************************
Invoke D3D9_Create_Interface
mov D3D9_Interface, eax
;**********************************************************************************************
;-_-_-winmain-_-_-_-_-_-_-_-_-_-_-_-_SET DX PARAMETERS-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
;**********************************************************************************************
IF DEBUG EQ 1
Invoke D3D9_Set_Present_Parameters, D3D9_Interface, addr D3D9_PresParam, WINDOW_WIDTH, WINDOW_HEIGHT, hwnd, TRUE
ELSE
Invoke D3D9_Set_Present_Parameters, D3D9_Interface, addr D3D9_PresParam, WINDOW_WIDTH, WINDOW_HEIGHT, hwnd, FALSE
ENDIF
;**********************************************************************************************
;-_-_-winmain-_-_-_-_-_-_-_-_-_-_-_-_CREATE DX9 DEVICE-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
;**********************************************************************************************
; Create Direct3D9 Device
Invoke D3D9_Create_Device, D3D9_Interface, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, D3DCREATE_HARDWARE_VERTEXPROCESSING,\
addr D3D9_PresParam, addr D3D9_Device
Here is the window callback procedure:
;**********************************************************************************************
;-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_WNDPROC-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
;-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_WNDPROC-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
;-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_WNDPROC-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
;**********************************************************************************************
ALIGN 16
MainWndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
;**********************************************************************************************
;-_-_-winproc-_-_-_-_-_-_-_-_-_-_-_-_WM_CREATE-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
;**********************************************************************************************
CREATE
Invoke SetTimer, hWnd, 1, 5000, NULL
;**********************************************************************************************
;-_-_-winproc-_-_-_-_-_-_-_-_-_-_-_-_WM_TIMER-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
;**********************************************************************************************
TIMER
Invoke SetForegroundWindow, hWnd
Invoke KillTimer, hWnd, 1
Invoke ShowCursor, 0
;**********************************************************************************************
;-_-_-winproc-_-_-_-_-_-_-_-_-_-_-_-_WM_CLOSE-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
;**********************************************************************************************
CLOSE
Invoke DestroyWindow, hWnd
;**********************************************************************************************
;-_-_-winproc-_-_-_-_-_-_-_-_-_-_-_-_WM_MOUSEMOVE-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
;**********************************************************************************************
MOUSEMOVE
; Trap mouse movement to avvoid windows resetting cursor
;**********************************************************************************************
;-_-_-winproc-_-_-_-_-_-_-_-_-_-_-_-_WM_SETCURSOR-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
;**********************************************************************************************
SETCURSOR
Invoke SetCursor, NULL
mov eax, TRUE
ret
;**********************************************************************************************
;-_-_-winproc-_-_-_-_-_-_-_-_-_-_-_-_WM_DESTROY-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
;**********************************************************************************************
DESTROY
Invoke ShowCursor, 1
Invoke PostQuitMessage, NULL
;**********************************************************************************************
;-_-_-winproc-_-_-_-_-_-_-_-_-_-_-_-_DEFAULT WINPROC-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
;**********************************************************************************************
.ELSE
DEFWNDPROC
;**********************************************************************************************
;-_-_-winproc-_-_-_-_-_-_-_-_-_-_-_-_RET ZERO JUMP HERE-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
;**********************************************************************************************
.ENDIF
RETNULL
MainWndProc endp
Here's how I usually do it; no timer, no setting a null cursor or other fiddling, and I've never noticed any problems..
WinMain {
RegisterClass...
CreateWindow...
set up D3D, change video mode, render state, etc.
ShowWindow...
ShowCursor(false)
message-loop, exit on quit
ShowCursor(true)
clean up...
return
}
qWord's recipe works perfectly for me:
Quote SWITCH uMsg
CASE WM_SETCURSOR
deb 1, "ShowCursor", wParam, lParam ; MasmBasic macro (http://www.masm32.com/board/index.php?topic=12460)
invoke ShowCursor, 0
return 1