AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

per-pixel alpha blended GUI demo
Goto page Previous  1, 2, 3 ... 10, 11, 12, 13  Next
 
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Ask for Help
View previous topic :: View next topic  
Author Message
Lexikos



Joined: 17 Oct 2006
Posts: 2739
Location: Australia, Qld

PostPosted: Sun Mar 02, 2008 2:05 am    Post subject: Reply with quote

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.
Code:
, "UInt", 0
Back to top
View user's profile Send private message
tic



Joined: 22 Apr 2007
Posts: 1375

PostPosted: Sun Mar 02, 2008 11:04 am    Post subject: Reply with quote

Code:
VarSetCapacity(pt, 8), NumPut(LayeredX, pt, 0), NumPut(LayeredY, pt, 4)
;...
, "UInt", &pt


that works, i had written 32 as the size Embarassed Smile 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
View user's profile Send private message
Lexikos



Joined: 17 Oct 2006
Posts: 2739
Location: Australia, Qld

PostPosted: Sun Mar 02, 2008 2:41 pm    Post subject: Reply with quote

tic wrote:
Code:
(LayeredX & 0xFFFFFFF) | LayeredY << 32

this does not work,
Rolling Eyes 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. Razz
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
View user's profile Send private message
tic



Joined: 22 Apr 2007
Posts: 1375

PostPosted: Sun Mar 02, 2008 3:51 pm    Post subject: Reply with quote

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
View user's profile Send private message
tic



Joined: 22 Apr 2007
Posts: 1375

PostPosted: Thu Mar 13, 2008 12:56 am    Post subject: Reply with quote

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
View user's profile Send private message
Lexikos



Joined: 17 Oct 2006
Posts: 2739
Location: Australia, Qld

PostPosted: Thu Mar 13, 2008 6:01 am    Post subject: Reply with quote

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
View user's profile Send private message
tic



Joined: 22 Apr 2007
Posts: 1375

PostPosted: Thu Mar 13, 2008 4:07 pm    Post subject: Reply with quote

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
View user's profile Send private message
Lexikos



Joined: 17 Oct 2006
Posts: 2739
Location: Australia, Qld

PostPosted: Thu Mar 13, 2008 11:57 pm    Post subject: Reply with quote

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? Wink
Back to top
View user's profile Send private message
tic



Joined: 22 Apr 2007
Posts: 1375

PostPosted: Fri Mar 14, 2008 6:32 am    Post subject: Reply with quote

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
View user's profile Send private message
Lexikos



Joined: 17 Oct 2006
Posts: 2739
Location: Australia, Qld

PostPosted: Fri Mar 14, 2008 8:24 am    Post subject: Reply with quote

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
View user's profile Send private message
tic



Joined: 22 Apr 2007
Posts: 1375

PostPosted: Sat Mar 15, 2008 12:27 pm    Post subject: Reply with quote

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 Rolling Eyes

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
View user's profile Send private message
tic



Joined: 22 Apr 2007
Posts: 1375

PostPosted: Wed Mar 19, 2008 8:39 pm    Post subject: Reply with quote

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
View user's profile Send private message
Lexikos



Joined: 17 Oct 2006
Posts: 2739
Location: Australia, Qld

PostPosted: Wed Mar 19, 2008 9:12 pm    Post subject: Reply with quote

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
View user's profile Send private message
tic



Joined: 22 Apr 2007
Posts: 1375

PostPosted: Wed Mar 19, 2008 11:40 pm    Post subject: Reply with quote

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
View user's profile Send private message
tic



Joined: 22 Apr 2007
Posts: 1375

PostPosted: Thu Mar 20, 2008 12:05 am    Post subject: Reply with quote

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
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Ask for Help All times are GMT
Goto page Previous  1, 2, 3 ... 10, 11, 12, 13  Next
Page 11 of 13

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group