应该将啥模块实例传递给 CreateCursor 方法?

Posted

技术标签:

【中文标题】应该将啥模块实例传递给 CreateCursor 方法?【英文标题】:What module instance should be passed to CreateCursor method?应该将什么模块实例传递给 CreateCursor 方法? 【发布时间】:2016-03-11 20:17:13 【问题描述】:

CreateCursor 函数将 HINSTANCE 作为第一个参数,如下所述: https://msdn.microsoft.com/en-us/library/windows/desktop/ms648385(v=vs.85).aspx

它可以是 NULL 但为什么首先需要它?我的猜测是它可用于查找应用程序主窗口并确定用于创建光标的显示驱动程序。但也许有人有更好的解释?

【问题讨论】:

因为它可以为 NULL,所以根本不需要 - 该函数只是忽略该值。也许在 Win16 中它很重要,只是为了兼容性而保留,或者它可能是为了将来的扩展而添加的,从未使用过。顺便说一句,没有“应用程序主窗口”这样的概念。 我的猜测是,它的存在是因为该参数需要用于加载或引用调用应用程序中的任何资源,类似于 LoadCursor,它基于资源创建自定义光标。所以它遵循类似的约定 imo。 【参考方案1】:

在我的 Windows Server 2008 R2 系统上,根本不使用句柄。这是添加了一些 cmets 的反汇编:

0:000> u createcursor
USER32!CreateCursor:
00000000`77a40cb4 488bc4          mov     rax,rsp
00000000`77a40cb7 48895808        mov     qword ptr [rax+8],rbx
00000000`77a40cbb 48896810        mov     qword ptr [rax+10h],rbp
00000000`77a40cbf 48897018        mov     qword ptr [rax+18h],rsi
00000000`77a40cc3 48897820        mov     qword ptr [rax+20h],rdi
00000000`77a40cc7 4154            push    r12
00000000`77a40cc9 4881ecc0000000  sub     rsp,0C0h
00000000`77a40cd0 33db            xor     ebx,ebx
0:000> u
USER32!CreateCursor+0x1e:
00000000`77a40cd2 458be1          mov     r12d,r9d
00000000`77a40cd5 418bf8          mov     edi,r8d
00000000`77a40cd8 3bd3            cmp     edx,ebx
00000000`77a40cda 8bf2            mov     esi,edx

;  If xHotSpot is negative, return error
00000000`77a40cdc 0f8c60070100    jl      USER32!CreateCursor+0xb0 (00000000`77a51442)
00000000`77a40ce2 413bd1          cmp     edx,r9d

;  If xHotSpot is greater than nWidth return error
00000000`77a40ce5 0f8f57070100    jg      USER32!CreateCursor+0xb0 (00000000`77a51442)
00000000`77a40ceb 443bc3          cmp     r8d,ebx
0:000> u
USER32!CreateCursor+0x36:

;  If yHotSpot is negative, return error
00000000`77a40cee 0f8c4e070100    jl      USER32!CreateCursor+0xb0 (00000000`77a51442)
00000000`77a40cf4 8bac24f0000000  mov     ebp,dword ptr [rsp+0F0h]
00000000`77a40cfb 443bc5          cmp     r8d,ebp

;  If yHotSpot is greater than nHeight return error
00000000`77a40cfe 0f8f3e070100    jg      USER32!CreateCursor+0xb0 (00000000`77a51442)

;  This LEA overwrites whatever was passed in as the application handle!!!
;  RCX was not saved before this point, so handle is lost
00000000`77a40d04 488d4c2430      lea     rcx,[rsp+30h]
00000000`77a40d09 33d2            xor     edx,edx
00000000`77a40d0b 41b888000000    mov     r8d,88h
00000000`77a40d11 e8828affff      call    USER32!memset (00000000`77a39798)

【讨论】:

以上是关于应该将啥模块实例传递给 CreateCursor 方法?的主要内容,如果未能解决你的问题,请参考以下文章

我应该将啥传递给 SQLitePCL.raw.SetProvider() 以避免“'Microsoft.Data.Sqlite.SqliteConnection' 的类型初始化程序引发异常”

将啥传递给 clf.predict()?

Equatable 的子类将啥传递给超级(Equatable 类)?

将啥传递给 sqlite create_function 任意指针

将啥传递给 Android 的 NDK 以便可以使用 OpenCV 加载图像?

我应该将啥 DbContext 与 EntityFrameworkCore 一起使用?