Help with Win32API needed

Started by ThallionDarkshine, May 20, 2012, 08:52:34 am

Previous topic - Next topic

ThallionDarkshine

May 20, 2012, 08:52:34 am Last Edit: May 20, 2012, 01:22:30 pm by ThallionDarkshine
So, for my RGSS Addon, I decided they I should use the win32api to set pixels and that sort of stuff. So, I got the handle of device context, and I tried to set several pixels in the window, but the function keeps returning -1 (failure). There's probably something that I'm missing, but could someone help me figure this out.

My code:
def win32test
@find_window = Win32API.new("user32", "FindWindow", "LL", "L")
@set_pixel = Win32API.new("gdi32", "SetPixel", "PIIP", "I")
window = @find_window.call("RGSS Player", "Test")
color = 0x00FF0000
result = @set_pixel.call(window, 0, 0, color)
print result
end

Blizzard

As far as I know, RMXP runs using DirectDraw so the backbuffer is probably locked to DirectDraw only and you can't use GDI on the window. Have you looked up what the error code -1 means?
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

ForeverZer0

I suggest taking a look into BitBlt.
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

ThallionDarkshine

In the Win32API documentation, -1 means that the method failed. If it succeeds it returns the rgb value of the pixel (I think).
I would try to use BitBlt, but I don't know where I'd get the handle of device context for the source image. However, I'll just keep looking through the documentation for something useful.

Blizzard

May 20, 2012, 02:54:24 pm #4 Last Edit: May 20, 2012, 02:57:36 pm by Blizzard
Actually I just remembered. I think you're doing it wrong in the first code. The device context is not the same as the window handle. Does the documentation except a DWORD or a HWND? Because if it's a DWORD, it's likely that you are sending it the wrong parameter. You will probably have to call GetDC with the HWND that you get from FindWindow and this will be then the device context which you pass on to SetPixel. Don't forget to call ReleaseDC afterwards or the whole game may break.

Look up GetDC and ReleaseDC in the MSDN docs. If I remember right, GetDC takes the HWND parameter and returns the device context while ReleaseDC takes the device context as parameter and returns an error code or 0 on success.
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

ThallionDarkshine

Alright, so now it gets to the find window command and shuts down. All I added were the getDC and releaseDC commands, and now it dies on the find window command. Here's my new code.


def win32test
    @find_window = Win32API.new("user32", "FindWindow", "PP", "P")
    @set_pixel = Win32API.new("gdi32", "SetPixel", "PIIP", "I")
    @get_dc = Win32API.new("user32", "GetDC","P","P")
    @release_dc = Win32API.new("user32", "ReleaseDC","PP","P")
    title = "Test"
    window = @find_window.call("RGSS Player", title)
    window2 = @get_dc.call(window)
    @release_dc.call(window, window2)
    color = 0x00FF0000
    result = @set_pixel.call(window, 0, 0, color)
    print result
  end

Blizzard

You are supposed to release the DC after the SetPixel call.

I think that FindWindow crashes because you changed the return type from "L" to "P" which is incorrect as HWND is an "L".

The documentation also says that SetPixel should be using "LIIL" as parameters and "L" as return type. Both HDC and COLORREF are actually DWORDs which are designated as "L".

Same for GetDC. It should be "L", "L".

And ReleaseDC should be "LL", "I".

You used "P" everywhere. "P" means pointer. It is used for array data and char strings, not for "ints" and "longs".
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

ThallionDarkshine

Thank you so much Blizzard, now how do you make it stay on the screen. It shows for a few seconds, and then vanishes. I have it redraw it in the update event, but it doesn't do any good.

Blizzard

You actually have to redraw it each time after Graphics.update was called. Graphics.update clears the backbuffer and redraws the whole scene so your manual drawing is also removed. The only way how you could keep something on the screen is if you created a Sprite in RMXP's scripts, created and assigned a Bitmap to it and drew your stuff on that Bitmap. Obviously the sprite should have a high z coordinate to always appear over all the other sprites.
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

ThallionDarkshine

But how would you make Win32 make it part of the bitmap of the sprite. All I see are commands to draw on the window.

Blizzard

Quote from: Blizzard on May 20, 2012, 05:59:58 pm
You actually have to redraw it each time after Graphics.update was called. Graphics.update clears the backbuffer and redraws the whole scene so your manual drawing is also removed. The only way how you could keep something on the screen is if you created a Sprite in RMXP's scripts, created and assigned a Bitmap to it and drew your stuff on that Bitmap. Obviously the sprite should have a high z coordinate to always appear over all the other sprites.


You do it all in RMXP. You don't need the Win32 API for that.
What are you actually trying to do? If you just want something to be visible on the screen all the time, you can really make that work with just a simple sprite.
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

ThallionDarkshine

Alright, I'll just use the built in bitmap methods for mine.