 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
Lexikos
Joined: 17 Oct 2006 Posts: 2739 Location: Australia, Qld
|
Posted: Sun Mar 02, 2008 2:05 am Post subject: |
|
|
Addition doesn't make sense in this context. It gets a close result, but is off by one on the Y axis.
The issue is with the way negative integers are formed. Since AutoHotkey uses 64-bit integers, -1 through -2147483648 are actually 0xFFFFFFFFFFFFFFFF through 0xFFFFFFFF80000000. Since the upper 32 bits are all set, bitwise OR will never change them. Where LayeredX is negative, LayeredX|LayeredH<<32 is the same as LayeredX|0xFFFFFFFF<<32. For a 32-bit integer, 0xFFFFFFFF is equivalent to -1...
What we need to do is discard the upper 32 bits of the X value:
| Code: | , "Int64*", (LayeredX & 0xFFFFFFF) | LayeredY << 32
| Alternatively, we could create a POINT structure in the typical sense:
| Code: | VarSetCapacity(pt, 8), NumPut(LayeredX, pt, 0), NumPut(LayeredY, pt, 4)
;...
, "UInt", &pt
| Also note:
| UpdateLayeredWindow wrote: | | If the current position is not changing, pptDst can be NULL. |
|
|
| Back to top |
|
 |
tic
Joined: 22 Apr 2007 Posts: 1375
|
Posted: Sun Mar 02, 2008 11:04 am Post subject: |
|
|
| Code: | VarSetCapacity(pt, 8), NumPut(LayeredX, pt, 0), NumPut(LayeredY, pt, 4)
;...
, "UInt", &pt |
that works, i had written 32 as the size but no worries. i will use that.
| Code: | | (LayeredX & 0xFFFFFFF) | LayeredY << 32 |
this does not work, but it doesnt really matter as i can just create the pt structure with numput as you have shown. just have to be sure to clear it. |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 2739 Location: Australia, Qld
|
Posted: Sun Mar 02, 2008 2:41 pm Post subject: |
|
|
| tic wrote: | | Code: | | (LayeredX & 0xFFFFFFF) | LayeredY << 32 |
this does not work, |
I tested the following with the script in my first post:
| Code: | | , "Int64*", (-640 & 0xFFFFFFFF) | 512 << 32 | I also tested with 640 in place of -640. Both gave the expected result, i.e. it does so work.
| Quote: | | just have to be sure to clear it. | There's no need to clear it if you are setting the X and Y before use. |
|
| Back to top |
|
 |
tic
Joined: 22 Apr 2007 Posts: 1375
|
Posted: Sun Mar 02, 2008 3:51 pm Post subject: |
|
|
I must have done something wrong then. I like the numput method. I'll continue writing on with my code, and although I dont need them it would be nice at some point to figure out writing text and also DrawImageFX.
I had tried this, but it didnt work. I'll get links for the documentation and everything when I try again, as I shouldnt expect you to do the legwork, so will get all available documentation when ive done a bit more on my program.
| Code: | DllCall("gdiplus\GdipCreateSolidFill", "Int", 0xFF000000, "UInt*", hBrush)
DllCall("gdiplus\GdipCreateStringFormat", "Int", 0, "Int", 0, "UInt*", hFormat)
DllCall("gdiplus\GdipCreateFontFamilyFromName", "Str", "Arial", "Int", 0, "UInt*", hFamily)
DllCall("gdiplus\GdipCreateFont", "UInt", hFamily, "Int", 10, "Int", 3, "UInt*", hFont)
hdc := DllCall("CreateCompatibleDC", "UInt", 0)
VarSetCapacity(rc, 16, 0)
NumPut(0.0, NumPut(0.0, rc, 8))
DllCall("FillRect", "UInt", hdc, "UInt", &rc, "UInt", DllCall("GetStockObject", "Int", 4))
DllCall("gdiplus\GdipMeasureString", "UInt", G, "Str", "String"
, "Int", -1, "UInt", hFont, "UInt", &rc, "UInt", hFormat, "UInt*", Size, "UInt*", 0, "UInt*", 0)
DllCall("gdiplus\GdipDrawString", "UInt", G, "Str", "String", "Int", -1, "UInt", hFont, "UInt", &rc, "UInt", hFormat, "UInt", hBrush) |
|
|
| Back to top |
|
 |
tic
Joined: 22 Apr 2007 Posts: 1375
|
Posted: Thu Mar 13, 2008 12:56 am Post subject: |
|
|
A quick question.....
If I create a bitmap from a file like so:
| Code: | | pBitmap := Gdip_CreateBitmapFromFile(File) |
How would I go about deleting the file afterwards, but still keep the Bitmap for later use so it doesnt need to be reloaded. Copy it in memory? I can delete it once Ive disposed of it, but then it can no longer be used.. |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 2739 Location: Australia, Qld
|
Posted: Thu Mar 13, 2008 6:01 am Post subject: |
|
|
See Bitmap and Image constructor dependencies.
| Quote: | | When either a Bitmap object or an Image object is constructed from a file, the file remains locked for the lifetime of the object. |
|
|
| Back to top |
|
 |
tic
Joined: 22 Apr 2007 Posts: 1375
|
Posted: Thu Mar 13, 2008 4:07 pm Post subject: |
|
|
| Quote: | 1. Construct the original Bitmap from the stream, from the memory, or from the file.
2. Create a new Bitmap of the same size, with a pixel format of more than 8 bits-per-pixel (BPP).
3. Use the Graphics.FromImage() method to obtain a Graphics object for the second Bitmap.
4. Use Graphics.DrawImage() to draw the first Bitmap onto the second Bitmap.
5. Use Graphics.Dispose() to dispose of the Graphics.
6. Use Bitmap.Dispose() to dispose of the first Bitmap. |
I tried that, but wasnt sure about step 3. which flat function would that be? I tried GdipGetImageGraphicsContext, but that wouldnt work. its a bitmap not an image right?
I then though that maybe i could clone it...
| Code: | #SingleInstance, Force
#NoEnv
DetectHiddenWindows, On
CoordMode, Mouse, Screen
SetBatchLines, -1
SetWinDelay, 0
pToken := Gdip_Startup()
Gui, 1: -Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs
Gui, 1: Show, w1 h1 Hide
hwnd1 := WinExist()
hbm := CreateDIBSection(150, 115, 32)
hdc := DllCall("CreateCompatibleDC", "UInt", 0)
hbmOld := DllCall("SelectObject", "UInt", hdc, "UInt", hbm)
G := Gdip_GraphicsFromHDC(hdc)
DllCall("gdiplus\GdipSetSmoothingMode", "UInt", G, "Int", 2)
pBitmap := Gdip_CreateBitmapFromFile("5.png")
;pBitmapClone := Gdip_CreateBitmap(150, 115, 0x26200A)
DllCall("gdip\GdipCloneBitmapAreaI", "Int", 0, "Int", 0, "Int", 150, "Int", 115, "Int", 0x26200A, "UInt", pBitmap, "UInt*", pBitmapClone)
Gdip_DrawImage(G, pBitmapClone, 0, 0, 150, 115, 0, 0, 150, 115, 1.0)
UpdateLayeredWindow(hwnd1, hdc, 0, 0, 150, 115)
Gui, 1: Show
Gdip_DisposeImage(pBitmap)
DllCall("DeleteObject", "UInt", hbm)
DllCall("DeleteDC", "UInt", hdc)
Gdip_DeleteGraphics(G)
Return |
That didnt work. Im not sure about the format. I've looked on msdn but couldnt figure out how to get the formats |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 2739 Location: Australia, Qld
|
Posted: Thu Mar 13, 2008 11:57 pm Post subject: |
|
|
| tic wrote: | | I tried GdipGetImageGraphicsContext, but that wouldnt work. its a bitmap not an image right? | It should work. A bitmap is a type of image.
| Quote: | | I've looked on msdn but couldnt figure out how to get the formats | What do you need "the formats" for? Why are you cloning the bitmap only to draw it onto another bitmap (i.e. clone the clone)?
Are you forgetting that you've already written working code that creates a bitmap and draws another bitmap onto it?  |
|
| Back to top |
|
 |
tic
Joined: 22 Apr 2007 Posts: 1375
|
Posted: Fri Mar 14, 2008 6:32 am Post subject: |
|
|
I'll have a look at the splash code i used previously and hopefully that will work.
if i am trying to draw a line using setpixel, then why doesnt this work:
| Code: | hbm := CreateDIBSection(100, 100, 32)
hdc := DllCall("CreateCompatibleDC", "UInt", 0)
hbmOld := DllCall("SelectObject", "UInt", hdc, "UInt", hbm)
G := Gdip_GraphicsFromHDC(hdc)
DllCall("gdiplus\GdipSetSmoothingMode", "UInt", G, "Int", 2)
pBitmap := Gdip_CreateBitmap(100, 100, 0x26200A)
VarSetCapacity(ARGB, 8)
NumPut(0xff, ARGB, 0)
NumPut(0xff, ARGB, 2)
NumPut(0x00, ARGB, 4)
NumPut(0x00, ARGB, 6)
x := 50
Loop, 20
{
DllCall("gdip\GdipBitmapSetPixel", "UInt", pBitmap, "Int", x, "Int", 50, "UInt", &ARGB)
x++
}
;GpStatus WINGDIPAPI GdipBitmapSetPixel(GpBitmap* bitmap, INT x, INT y, ARGB color)
Gdip_DrawImage(G, pBitmap, 0, 0, 100, 100, 0, 0, 100, 100, 1.0)
UpdateLayeredWindow(hwnd1, hdc, 0, 0, 100, 100) |
i have tried several methods of setting the colour, and none seem to work. i am just trying to get setpixel to work (i know there are better ways to draw a line) |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 2739 Location: Australia, Qld
|
Posted: Fri Mar 14, 2008 8:24 am Post subject: |
|
|
| Code: | DllCall("gdip\GdipBitmapSetPixel", "UInt", pBitmap, "Int", x, "Int", 50, "UInt", &ARGB)
|
- Dll name.
- The final parameter is a 32-bit colour value, not a pointer to a 64-bit structure.
|
|
| Back to top |
|
 |
tic
Joined: 22 Apr 2007 Posts: 1375
|
Posted: Sat Mar 15, 2008 12:27 pm Post subject: |
|
|
Heh. It wasnt the colour (although it was, but i had written in correctly the 1st time and then tried changing it) it was the fact that i wrote gdip
I've had a look and cant find anything to suggest this, but is there a setting that may be set to alter resize quality, similar to:
| Code: | | DllCall("gdiplus\GdipSetSmoothingMode", "UInt", G, "Int", 2) |
for antialiasing. Some of the images I make smaller dont appear great quality.
Edit: Lexikos sent me the answer for anyone else:
| Code: | | DllCall("gdiplus\GdipSetInterpolationMode", "UInt", G, "Int", 6) |
or 7 is good as well |
|
| Back to top |
|
 |
tic
Joined: 22 Apr 2007 Posts: 1375
|
Posted: Wed Mar 19, 2008 8:39 pm Post subject: |
|
|
I am wanting to create the new magnifier as you know, and wanted to write it using gdi+ also. I have tried several times but it always gives a garbled window.
Ideally I would like to create a bitmap and fill it with black (i know hoe to do this), then capture a portion of the screen ( i get confused here. should i get the dc of the screen and bitblt?) and draw (bitblt?) it onto the bitmap, then get the handle for the current cursor (i can also do this), draw this onto the bitmap, and resize the graphics with DrawImage.
I have been confused about the order of things, and which DCs to use with bitblt. thanks
is #autohotkey down? |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 2739 Location: Australia, Qld
|
Posted: Wed Mar 19, 2008 9:12 pm Post subject: |
|
|
I suppose:
- Create a bitmap the "unzoomed" size of the magnifier display window and get a device context from it.
- Get a device context from the screen and BitBlt from screen to bitmap.
- Draw the cursor onto the bitmap.
- Draw (and resize) the bitmap onto the window.
GDI+ won't be of much help since you need GDI to capture the screen. |
|
| Back to top |
|
 |
tic
Joined: 22 Apr 2007 Posts: 1375
|
Posted: Wed Mar 19, 2008 11:40 pm Post subject: |
|
|
I quickly wrote a version with no zooming (hence keeping stretchblt for when i do zoom):
| Code: | #SingleInstance, Force
#NoEnv
DetectHiddenWindows, On
CoordMode, Mouse, Screen
SetBatchLines, -1
SetWinDelay, 0
SetWorkingDir %A_ScriptDir%
GuiWidth := 1280, GuiHeight := 400
hBrush := DllCall("CreateSolidBrush", "Int", 0x000000)
VarSetCapacity(RC, 16)
NumPut(0, RC, 0), NumPut(0, RC, 4)
Gui, 1: +LastFound +ToolWindow -Caption +AlwaysOnTop
hwnd1 := WinExist()
Gui, 1: Show, x0 y0 w%GuiWidth% h%GuiHeight%
WinSet, ExStyle, +0x00000020, ahk_id %hwnd1%
WinSet, Transparent, 254, ahk_id %hwnd1%
hsc := DllCall("GetDC", "UInt", 0)
hdc := DllCall("GetDC", "UInt", hwnd1)
bdc := DllCall("CreateCompatibleDC", "UInt", 0)
hbm := CreateDIBSection(bdc, GuiWidth, GuiHeight)
obm := DllCall("SelectObject", "UInt", bdc, "UInt", hbm)
Loop
{
MouseGetPos, x, y
NumPut(GuiWidth, RC, 8), NumPut(GuiHeight, RC, 12)
DllCall("FillRect", "UInt", bdc, "UInt", &RC, "UInt", hBrush)
BitBlt(bdc, 0, 0, GuiWidth, GuiHeight, hsc, x-(GuiWidth//2), y-(GuiHeight//2))
StretchBlt(hdc, 0, 0, GuiWidth, GuiHeight, bdc, 0, 0, GuiWidth, GuiHeight)
Sleep, 30
}
Return
Esc::ExitApp
;###############################################################################
CreateDIBSection(hDC, nW, nH, bpp=32, ByRef pBits ="")
{
NumPut(VarSetCapacity(bi, 40, 0), bi)
NumPut(nW, bi, 4)
NumPut(nH, bi, 8)
NumPut(bpp, NumPut(1, bi, 12, "UShort"), 0, "UShort")
NumPut(0, bi,16)
Return, DllCall("gdi32\CreateDIBSection", "UInt", hDC, "UInt", &bi, "UInt", 0, "UInt*", pBits, "UInt", 0, "UInt", 0)
}
BitBlt(DestDC, Destx, Desty, Destw, Desth, SourceDC, Sourcex, Sourcey, Raster="")
{
If !Raster
Raster := 0x40000000|0x00CC0020
DllCall("gdi32\BitBlt"
, "UInt", DestDC ; handle to destination DC
, "Int", Destx ; x-coord of destination upper-left corner
, "Int", Desty ; y-coord of destination upper-left corner
, "Int", Destw ; width of destination rectangle
, "Int", Desth ; height of destination rectangle
, "UInt", SourceDC ; handle to source DC
, "Int", Sourcex ; x-coordinate of source upper-left corner
, "Int", Sourcey ; y-coordinate of source upper-left corner
, "UInt", Raster) ; raster operation code
}
StretchBlt(DestDC, Destx, Desty, Destw, Desth, SourceDC, Sourcex, Sourcey, Sourcew, Sourceh, Raster="")
{
If !Raster
Raster := 0x00CC0020
DllCall("gdi32\StretchBlt"
, "UInt", DestDC ; handle to destination DC
, "Int", Destx ; x-coord of destination upper-left corner
, "Int", Desty ; y-coord of destination upper-left corner
, "Int", Destw ; width of destination rectangle
, "Int", Desth ; height of destination rectangle
, "UInt", SourceDC ; handle to source DC
, "Int", Sourcex ; x-coordinate of source upper-left corner
, "Int", Sourcey ; y-coordinate of source upper-left corner
, "Int", Sourcew ; width of source rectangle
, "Int", Sourceh ; height of source rectangle
, "UInt", Raster) ; raster operation code
} |
I am wondering why on my computer the cursor appears to flicker. The cpu usage is minimal. Also, of the methods we discussed before, which do you think would be best for not showing the actual magnifier gui even on vista with aero? |
|
| Back to top |
|
 |
tic
Joined: 22 Apr 2007 Posts: 1375
|
Posted: Thu Mar 20, 2008 12:05 am Post subject: |
|
|
Even if my loop only contains:
| Code: | Loop
{
MouseGetPos, x, y
BitBlt(hdc, 0, 0, GuiWidth, GuiHeight, hsc, x-(GuiWidth//2), y-(GuiHeight//2))
Sleep, 30
}
Return |
then the cursor still flickers. i wonder why |
|
| Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|