【问题标题】:Having problems with GdiGradientFill in FASMFASM 中的 GdiGradientFill 存在问题
【发布时间】:2013-01-03 01:19:09
【问题描述】:

我正在尝试编写我最近开发的 Java 应用程序的 ASM 版本,作为 Win32 ASM 中的一个项目,但正如标题所述,我遇到了 GdiGradientFill 问题;目前,我更喜欢使用 FASM,并避免使用更高级别的 ASM 构造,例如 INVOKE 和使用 WIN32 包含。

我有什么,atm:

PUSH    [hWnd]                                                  
CALL    [User32.GetWindowDC]                                
MOV     [hDC], EAX                          
PUSH    rectClient                              
PUSH    [hWnd]                          
CALL    [User32.GetClientRect]  

PUSH    [rectClient.left]
POP     [colorOne.xPos]
PUSH    [rectClient.top]
POP     [colorOne.yPos] 
MOV     [colorOne.red],     0xC000
MOV     [colorOne.green],   0xC000
MOV     [colorOne.blue],    0xC000
MOV     [colorOne.alpha],   0x0000

PUSH    [rectClient.right]
POP     [colorTwo.xPos]
PUSH    [rectClient.bottom]
POP     [colorTwo.yPos] 
MOV     [colorTwo.red],     0x0000
MOV     [colorTwo.green],   0x2800
MOV     [colorTwo.blue],    0x7700
MOV     [colorTwo.alpha],   0x0C00

MOV     [gRect.UpperLeft],  0
MOV     [gRect.LowerRight], 1

PUSH    GRADIENT_FILL_RECT_H                            
PUSH    1                               
PUSH    gRect                               
PUSH    2                           
PUSH    colorOne                            
PUSH    [hDC]                               
CALL    [GDI32.GdiGradientFill]

但是,代码只返回一个 FALSE,并且经过 MSDN 之后 (http://msdn.microsoft.com/en-us/library/windows/desktop/dd373585(v=vs.85).aspx)

还有一些其他的例子(http://www.asmcommunity.net/board/index.php?topic=4100.0),我还是看不出我做错了什么,谁能看到这里的缺陷?

另一个问题是我尝试使用 Msimg32 的 GradientFill,因为这总是会导致崩溃,但是,我看到一些报告说 Win2K+ 操作系统只是将参数从 Msimg32 传递到 GDI32;这是准确的,还是其他人在使用此表单时遇到过问题?

整个代码的粘贴链接:http://pastebin.com/GEHDw6Qe

感谢您的帮助,SS

编辑: 代码现在正在运行,老实说,我不知道发生了什么变化,除了将 PUSH / POP 序列更改为 MOV EAX、[rectClient.left] 等( PUSH / POP 方法也有效)- 非常感谢那些提供帮助的人!

【问题讨论】:

    标签: winapi assembly fasm


    【解决方案1】:

    您正在将看起来像 RECT 的内容作为第 4 个参数传递给 GdiGradientFill。该函数需要一个 GRADIENT_TRIANGLE。

    此外,PUSH/POP 是一种从一个内存位置复制到另一个内存位置的非常奇怪的方式。您正在执行 4 次内存访问,而不是 2 次。通过寄存器复制;这不是 Java。

    您确定 GetWindowDC 是您所需要的吗?那个返回整个窗口、标题和边框等的 DC。对于客户区,人们通常使用 GetDC()。完成后,调用 ReleaseDC()。

    【讨论】:

    • 来自 MSDN:pMesh [in] 三角形模式下的 GRADIENT_TRIANGLE 结构数组,或矩形模式下的 GRADIENT_RECT 结构数组。另外,我知道 PUSH / POP 不是理想的方法,但这只是暂时的,试图解决这个问题。虽然方法很奇怪,但是会不会导致这个功能失效?
    • 糟糕——你是对的,它应该是 GRADIENT_RECT。 PUSH/POP 不会受到伤害,只是次优。无论如何 - 你调用 GetLastError() 了吗?
    • 嗯,我现在有 - 没有错误;在逐步使用 ollyDbg 时,我得到了可行的对话,但没有背景。
    • 您确定 GetWindowDC 是您所需要的吗?那个返回整个窗口、标题和边框等的 DC。对于客户区,人们通常使用 GetDC()。完成后,调用 ReleaseDC()。
    • 我也尝试过使用 GetDC;我相信,我从中得到了有效的回应,因为我最初是在尝试使用一系列带的方法,每个带的阴影不同,FillRect - 虽然这确实绘制了窗口,但“外观”还不够。跨度>
    猜你喜欢
    • 2012-06-07
    • 1970-01-01
    • 2013-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-12
    • 2012-09-17
    • 1970-01-01
    相关资源
    最近更新 更多