在FASM中遇到GdiGradientFill问题

时间:2013-01-03 01:19:10

标签: winapi assembly fasm

我正在尝试编写我最近开发的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 + OS只是将参数从Msimg32传递给GDI32;这是准确的,还是有其他人遇到过这种形式的问题?

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

感谢您的帮助,SS

编辑: 代码现在正在工作,老实说,我不知道发生了什么变化,除了将PUSH / POP序列更改为MOV EAX,[rectClient.left]等外,我看不出先前和现在工作数据之间有什么不同。 PUSH / POP方法也适用) - 非常感谢那些提供帮助的人!

1 个答案:

答案 0 :(得分:1)

你将看起来像RECT的东西作为第四个参数传递给GdiGradientFill。该函数需要GRADIENT_TRIANGLE。

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

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