如何使用私有核心图形方法以编程方式缩放屏幕(如何查找函数参数)

Posted

技术标签:

【中文标题】如何使用私有核心图形方法以编程方式缩放屏幕(如何查找函数参数)【英文标题】:How to zoom the screen programmatically with private coregraphic methods (how to find function arguments) 【发布时间】:2012-10-17 12:36:52 【问题描述】:

您可能知道 Mac OS X 内置了一个非常不错的屏幕缩放功能,可以在系统偏好设置 => 通用访问中启用。

现在我正在尝试以编程方式触发此屏幕缩放。我可以通过发送键盘快捷键来做到这一点,但它不像它应该的那样流畅。所以我对系统如何做到这一点进行了一些研究。

似乎有一些私有核心图形方法可以做我想做的事,但我无法找到它们采用的参数。

这些是我发现的功能:

CGSZoomPoint CGSUzoomPoint CGSGetZoomParameters CGSSetZoomParameters CGSIsZoomed

有些人已经对核心图形框架的一些私有方法进行了逆向工程,并为它们创建了标头。 (参见例如http://pwproject.googlecode.com/svn/trunk/Mac%20OS%20X/Vector%20Grab/) 不幸的是,我似乎需要的方法不见了。 (CGSIsZoomed,其实是包含的

CG_EXTERN CGError CGSIsZoomed(CGSConnectionID cid, bool *outIsZoomed); 

)

我还发现了一个似乎可以缩放屏幕的应用程序,这似乎是相关的反汇编,但我对汇编不太了解,因此我看不懂;-(

0000000100015c21    callq   0x10002c212 ; symbol stub for: _CGEventCreate
0000000100015c26    movq    %rax,%rbx
0000000100015c29    movq    %rbx,%rdi
0000000100015c2c    callq   0x10002c22a ; symbol stub for: _CGEventGetLocation
0000000100015c31    movsd   %xmm0,0xffffff48(%rbp)
0000000100015c39    movsd   %xmm1,0xffffff58(%rbp)
0000000100015c41    movsd   %xmm0,0xa8(%rbp)
0000000100015c46    movsd   %xmm1,0xb0(%rbp)
0000000100015c4b    movq    %rbx,%rdi
0000000100015c4e    callq   0x10002c362 ; symbol stub for: _CFRelease
0000000100015c5a    jle 0x100015d01
0000000100015c60    movq    0x00098a71(%rip),%rax
0000000100015c67    movq    0x18(%rax),%rcx
0000000100015c6b    movq    %rcx,0x18(%rsp)
0000000100015c70    movq    0x10(%rax),%rcx
0000000100015c74    movq    %rcx,0x10(%rsp)
0000000100015c79    movq    (%rax),%rcx
0000000100015c7c    movq    0x08(%rax),%rax
0000000100015c80    movq    %rax,0x08(%rsp)
0000000100015c85    movq    %rcx,(%rsp)
0000000100015c89    movsd   0xffffff48(%rbp),%xmm0
0000000100015c91    movsd   0xffffff58(%rbp),%xmm1
0000000100015c99    callq   0x10002c266 ; symbol stub for: _CGRectContainsPoint
0000000100015c9e    cmpl    $0x02,0x00098a43(%rip)
0000000100015ca5    jl  0x100015d01
0000000100015ca7    movl    $0x    00000001,%r15d
0000000100015cad    movl    $0x00000020,%ebx
0000000100015cb2    movsd   0xa8(%rbp),%xmm0
0000000100015cb7    movsd   0xb0(%rbp),%xmm1
0000000100015cbc    movq    0x00098a15(%rip),%rax
0000000100015cc3    movq    0x18(%rax,%rbx),%rcx
0000000100015cc8    movq    %rcx,0x18(%rsp)
0000000100015ccd    movq    0x10(%rax,%rbx),%rcx
0000000100015cd2    movq    %rcx,0x10(%rsp)
0000000100015cd7    movq    (%rax,%rbx),%rcx
0000000100015cdb    movq    0x08(%rax,%rbx),%rax
0000000100015ce0    movq    %rax,0x08(%rsp)
0000000100015ce5    movq    %rcx,(%rsp)
0000000100015ce9    callq   0x10002c266 ; symbol stub for: _CGRectContainsPoint
0000000100015cee    addq    $0x20,%rbx
0000000100015cf2    incq    %r15
0000000100015cf5    movslq  0x000989ec(%rip),%rax
0000000100015cfc    cmpq    %rax,%r15
0000000100015cff    jl  0x100015cb2
0000000100015d01    movsd   0xc0(%rbp),%xmm0
0000000100015d06    movsd   %xmm0,0xffffff58(%rbp)
0000000100015d0e    leaq    0xa8(%rbp),%rsi
0000000100015d12    leaq    0x98(%rbp),%rdx
0000000100015d16    movl    %r14d,%edi
0000000100015d19    callq   0x10002c296 ; symbol stub for: _CGSZoomPoint
0000000100015d1e    movsd   0xffffff58(%rbp),%xmm2
0000000100015d26    testl   %eax,%eax
0000000100015d28    jne 0x100015d99
0000000100015d2a    movapd  %xmm2,%xmm0
0000000100015d2e    mulsd   0xffffff60(%rbp),%xmm0
0000000100015d36    addsd   0x98(%rbp),%xmm0
0000000100015d3b    movsd   0x00017255(%rip),%xmm1
0000000100015d43    ucomisd %xmm0,%xmm1
0000000100015d47    ja  0x100015d78
0000000100015d49    ucomisd 0x0001749f(%rip),%xmm0
0000000100015d51    ja  0x100015d78
0000000100015d53    mulsd   0xffffff50(%rbp),%xmm2
0000000100015d5b    addsd   0xa0(%rbp),%xmm2
0000000100015d60    movsd   0x00017230(%rip),%xmm0
0000000100015d68    ucomisd %xmm2,%xmm0
0000000100015d6c    ja  0x100015d78
0000000100015d6e    ucomisd 0x00017482(%rip),%xmm2
0000000100015d76    jbe 0x100015d99
0000000100015d78    movzbl  0xbf(%rbp),%edx
0000000100015d7c    andl    $0x01,%edx
0000000100015d7f    movsd   0xc0(%rbp),%xmm0
0000000100015d84    leaq    0xc8(%rbp),%rsi
0000000100015d88    movl    %r14d,%edi
0000000100015d8b    movl    $0x    00000001,%ecx
0000000100015d90    xorpd   %xmm1,%xmm1
0000000100015d94    callq   0x10002c290 ; symbol stub for: _CGSSetZoomParameters
0000000100015d99    movsd   0xffffff70(%rbp),%xmm1
0000000100015da1    addsd   0xffffff50(%rbp),%xmm1
0000000100015da9    movsd   0xffffff68(%rbp),%xmm0
0000000100015db1    addsd   0xffffff60(%rbp),%xmm0
0000000100015db9    movb    0x000988f1(%rip),%al
0000000100015dbf    xorl    %edi,%edi
0000000100015dc1    cmpb    $0x01,%al
0000000100015dc3    jne 0x100015dde
0000000100015dc5    movl    $0x    00000006,%esi
0000000100015dca    xorl    %edx,%edx

如果有人知道如何使用这些私有功能,你会很高兴 :-)

最好, 托马斯

【问题讨论】:

我也有一个想法,我需要以编程方式缩放屏幕。执行它的应用程序的名称是什么? 你能告诉我你是否找到了一些解决方案,因为我现在正在寻找这种方法几天 【参考方案1】:

这个问题已经很久没有答案了,但碰巧我只是想出了如何在我自己的工作中使用CGSGetZoomParametersCGSSetZoomParameters,它们都可以用来控制和检索关于屏幕的缩放状态。函数定义为:

CG_EXTERN CGError CGSGetZoomParameters(CGSConnectionID cid, CGPoint *origin, double * zoomFactor, int8_t *smoothed);
CG_EXTERN CGError CGSSetZoomParameters(CGSConnectionID cid, CGPoint *origin, double zoomFactor, int8_t smoothed);

origin 使用以下方法确定屏幕的哪个部分被缩放:

要尽可能向左缩放区域,请将origin.x 设置为:(desktopWidth / 2) / zoomFactor

要尽可能向右缩放区域,请将origin.x 设置为:desktopWidth - ((desktopWidth / 2) / zoomFactor)

要尽可能放大区域,请将origin.y 设置为:(desktopHeight / 2) / zoomFactor

要尽可能向右缩放区域,请将origin.y 设置为:desktopHeight - ((desktopHeight / 2) / zoomFactor)

对于desktopWidthdesktopHeight,是当前桌面边界矩形的总宽度/高度,包括当前排列的所有显示器。因此,如果您有两个完全水平排列的 1080p 显示器,则桌面的总宽度和高度为 3840x1080。

要缩放中间区域,请使用介于两个极值之间的 origin 值。数学计算得出,它们之间的整数点数完全对应于任何给定zoomFactor 的缩放屏幕可以具有的位置数。

这些功能是低级的,会干扰标准的 macOS 无障碍缩放功能。例如,如果您的屏幕未缩放,您可以使用CGSSetZoomParameters 将其放大,然后使用一种辅助功能(如按住 Control 并滚动鼠标滚轮来更改缩放),它们将像屏幕未缩放一样工作。此外,屏幕缩放时,无论无障碍缩放功能如何配置,都无法使用鼠标进行平移,因此请注意!您可能会导致屏幕放大并让用户无法再次缩小。

我不确定CGSZoomPointCGSUnzoomPoint 是如何使用的——我无法让它们产生任何效果。但如前所述,屏幕缩放的低级控制可以通过其他两个功能来完成。

【讨论】:

以上是关于如何使用私有核心图形方法以编程方式缩放屏幕(如何查找函数参数)的主要内容,如果未能解决你的问题,请参考以下文章

如何以编程方式缩放网页视图?

Android如何以编程方式调整(缩放)xml矢量图标

如何以编程方式检测屏幕撕裂?

如何以编程方式确定浏览器窗口的当前缩放级别? [复制]

如何以编程方式访问 Android 操作系统的私有字符串?

如何以编程方式将 UIImageView 缩放到固定宽度和灵活高度?