Results 1 to 27 of 27

Thread: [RESOLVED] GetActiveWindow question for screen capture app

  1. #1

    Thread Starter
    vbuggy krtxmrtz's Avatar
    Join Date
    May 2002
    Location
    In a probability cloud
    Posts
    5,573

    Resolved [RESOLVED] GetActiveWindow question for screen capture app

    I want to capture the active window by using its handle:

    hnd = GetDC(GetActiveWindow)

    and then copying to a picturebox:

    BitBlt Picture1.hDC, 0, 0, width, height, hnd, 0, 0, SRCCOPY

    but I don't know how to get the parameters width and height to adjust the size of Picture1.
    Last edited by krtxmrtz; Sep 3rd, 2010 at 08:36 AM.
    Lottery is a tax on people who are bad at maths
    If only mosquitoes sucked fat instead of blood...
    To do is to be (Descartes). To be is to do (Sartre). To be do be do (Sinatra)

  2. #2
    Discovering Life Siddharth Rout's Avatar
    Join Date
    Feb 2005
    Location
    Mumbai, India
    Posts
    12,001

    Re: GetActiveWindow question

    Something like this?

    Code:
    Private Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal x As Long, _
    ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, _
    ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long
    
    Private Declare Function GetWindowDC Lib "user32" (ByVal hwnd As Long) As Long
    
    Private Sub Command1_Click()
        Dim lCurHwnd As Long
        lCurHwnd = GetWindowDC(GetActiveWindow)
        Picture1.Cls
        Picture1.Height = Me.ScaleHeight + 60
        Picture1.Width = Me.ScaleWidth + 60
    
        BitBlt Picture1.hDC, 0, 0, _
        Picture1.Height, Picture1.Width, lCurHwnd, 0, 0, vbSrcCopy
    End Sub
    A good exercise for the Heart is to bend down and help another up...
    Please Mark your Thread "Resolved", if the query is solved


    MyGear:
    ★ CPU ★ Ryzen 5 5800X
    ★ GPU ★ NVIDIA GeForce RTX 3080 TI Founder Edition
    ★ RAM ★ G. Skill Trident Z RGB 32GB 3600MHz
    ★ MB ★ ASUS TUF GAMING X570 (WI-FI) ATX Gaming
    ★ Storage ★ SSD SB-ROCKET-1TB + SEAGATE 2TB Barracuda IHD
    ★ Cooling ★ NOCTUA NH-D15 CHROMAX BLACK 140mm + 10 of Noctua NF-F12 PWM
    ★ PSU ★ ANTEC HCG-1000-EXTREME 1000 Watt 80 Plus Gold Fully Modular PSU
    ★ Case ★ LIAN LI PC-O11 DYNAMIC XL ROG (BLACK) (G99.O11DXL-X)
    ★ Monitor ★ LG Ultragear 27" 240Hz Gaming Monitor
    ★ Keyboard ★ TVS Electronics Gold Keyboard
    ★ Mouse ★ Logitech G502 Hero

  3. #3
    Discovering Life Siddharth Rout's Avatar
    Join Date
    Feb 2005
    Location
    Mumbai, India
    Posts
    12,001

    Re: GetActiveWindow question

    One more way to do what you want...

    PS: Not my code...

    Code:
    Private Declare Sub keybd_event Lib "user32" (ByVal bVk As Byte, _
    ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long)
    
    Private Const KEYEVENTF_KEYUP = &H2
    
    Private Sub Command1_Click()
        ' capture the contents of the active window to a picture box
        Set Picture1.Picture = GetScreenBitmap(True)
    End Sub
    
    Function GetScreenBitmap(Optional ActiveWindow As Boolean) As Picture
        ' save the current picture in the clipboard, if any
        Dim pic As StdPicture
        Set pic = Clipboard.GetData(vbCFBitmap)
        
        ' Alt-Print Screen captures the active window only
        If ActiveWindow Then
            ' Press the Alt key
            keybd_event vbKeyMenu, 0, 0, 0
        End If
        ' Press the Print Screen key
        keybd_event vbKeySnapshot, 0, 0, 0
        DoEvents
    
        ' Release the Print Screen key
        keybd_event vbKeySnapshot, 0, KEYEVENTF_KEYUP, 0
        If ActiveWindow Then
            ' Release the Alt key
            keybd_event vbKeyMenu, 0, KEYEVENTF_KEYUP, 0
        End If
        DoEvents
        
        ' return the bitmap now in the clipboard
        Set GetScreenBitmap = Clipboard.GetData(vbCFBitmap)
        ' restore the original contents of the clipboard
        Clipboard.SetData pic, vbCFBitmap
        
    End Function
    A good exercise for the Heart is to bend down and help another up...
    Please Mark your Thread "Resolved", if the query is solved


    MyGear:
    ★ CPU ★ Ryzen 5 5800X
    ★ GPU ★ NVIDIA GeForce RTX 3080 TI Founder Edition
    ★ RAM ★ G. Skill Trident Z RGB 32GB 3600MHz
    ★ MB ★ ASUS TUF GAMING X570 (WI-FI) ATX Gaming
    ★ Storage ★ SSD SB-ROCKET-1TB + SEAGATE 2TB Barracuda IHD
    ★ Cooling ★ NOCTUA NH-D15 CHROMAX BLACK 140mm + 10 of Noctua NF-F12 PWM
    ★ PSU ★ ANTEC HCG-1000-EXTREME 1000 Watt 80 Plus Gold Fully Modular PSU
    ★ Case ★ LIAN LI PC-O11 DYNAMIC XL ROG (BLACK) (G99.O11DXL-X)
    ★ Monitor ★ LG Ultragear 27" 240Hz Gaming Monitor
    ★ Keyboard ★ TVS Electronics Gold Keyboard
    ★ Mouse ★ Logitech G502 Hero

  4. #4

    Thread Starter
    vbuggy krtxmrtz's Avatar
    Join Date
    May 2002
    Location
    In a probability cloud
    Posts
    5,573

    Re: GetActiveWindow question

    The problem is, the program delays the capture for a few seconds to allow the user to select any other window -sorry I forgot to mention this, so Me still refers to the app window and not to the selected one.
    Lottery is a tax on people who are bad at maths
    If only mosquitoes sucked fat instead of blood...
    To do is to be (Descartes). To be is to do (Sartre). To be do be do (Sinatra)

  5. #5
    Discovering Life Siddharth Rout's Avatar
    Join Date
    Feb 2005
    Location
    Mumbai, India
    Posts
    12,001

    Re: GetActiveWindow question

    Use a timer or use doevents?
    A good exercise for the Heart is to bend down and help another up...
    Please Mark your Thread "Resolved", if the query is solved


    MyGear:
    ★ CPU ★ Ryzen 5 5800X
    ★ GPU ★ NVIDIA GeForce RTX 3080 TI Founder Edition
    ★ RAM ★ G. Skill Trident Z RGB 32GB 3600MHz
    ★ MB ★ ASUS TUF GAMING X570 (WI-FI) ATX Gaming
    ★ Storage ★ SSD SB-ROCKET-1TB + SEAGATE 2TB Barracuda IHD
    ★ Cooling ★ NOCTUA NH-D15 CHROMAX BLACK 140mm + 10 of Noctua NF-F12 PWM
    ★ PSU ★ ANTEC HCG-1000-EXTREME 1000 Watt 80 Plus Gold Fully Modular PSU
    ★ Case ★ LIAN LI PC-O11 DYNAMIC XL ROG (BLACK) (G99.O11DXL-X)
    ★ Monitor ★ LG Ultragear 27" 240Hz Gaming Monitor
    ★ Keyboard ★ TVS Electronics Gold Keyboard
    ★ Mouse ★ Logitech G502 Hero

  6. #6

    Thread Starter
    vbuggy krtxmrtz's Avatar
    Join Date
    May 2002
    Location
    In a probability cloud
    Posts
    5,573

    Re: GetActiveWindow question

    Quote Originally Posted by koolsid View Post
    Use a timer or use doevents?
    I'm using the Timer function with DoEvents:
    Code:
    Private Sub Wait(sec As Single)
        'Pause sec seconds
        Dim tim As Single
    
        tim = Timer
        While Timer < tim + sec
            DoEvents
        Wend
    End Sub
    Lottery is a tax on people who are bad at maths
    If only mosquitoes sucked fat instead of blood...
    To do is to be (Descartes). To be is to do (Sartre). To be do be do (Sinatra)

  7. #7
    Discovering Life Siddharth Rout's Avatar
    Join Date
    Feb 2005
    Location
    Mumbai, India
    Posts
    12,001

    Re: GetActiveWindow question

    I would suggest not to use DoEvents in a loop but to set the timer for specific number of seconds in the design time...
    A good exercise for the Heart is to bend down and help another up...
    Please Mark your Thread "Resolved", if the query is solved


    MyGear:
    ★ CPU ★ Ryzen 5 5800X
    ★ GPU ★ NVIDIA GeForce RTX 3080 TI Founder Edition
    ★ RAM ★ G. Skill Trident Z RGB 32GB 3600MHz
    ★ MB ★ ASUS TUF GAMING X570 (WI-FI) ATX Gaming
    ★ Storage ★ SSD SB-ROCKET-1TB + SEAGATE 2TB Barracuda IHD
    ★ Cooling ★ NOCTUA NH-D15 CHROMAX BLACK 140mm + 10 of Noctua NF-F12 PWM
    ★ PSU ★ ANTEC HCG-1000-EXTREME 1000 Watt 80 Plus Gold Fully Modular PSU
    ★ Case ★ LIAN LI PC-O11 DYNAMIC XL ROG (BLACK) (G99.O11DXL-X)
    ★ Monitor ★ LG Ultragear 27" 240Hz Gaming Monitor
    ★ Keyboard ★ TVS Electronics Gold Keyboard
    ★ Mouse ★ Logitech G502 Hero

  8. #8

    Thread Starter
    vbuggy krtxmrtz's Avatar
    Join Date
    May 2002
    Location
    In a probability cloud
    Posts
    5,573

    Re: GetActiveWindow question

    Quote Originally Posted by koolsid View Post
    I would suggest not to use DoEvents in a loop but to set the timer for specific number of seconds in the design time...
    Are you actually suggesting I use a timer control rather than the Timer function?

    At any rate this is a side issue and the main question about how to retrieve the captured window dimensions remains open.
    Lottery is a tax on people who are bad at maths
    If only mosquitoes sucked fat instead of blood...
    To do is to be (Descartes). To be is to do (Sartre). To be do be do (Sinatra)

  9. #9
    Discovering Life Siddharth Rout's Avatar
    Join Date
    Feb 2005
    Location
    Mumbai, India
    Posts
    12,001

    Re: GetActiveWindow question

    Are you actually suggesting I use a timer control rather than the Timer function?
    Yes

    At any rate this is a side issue and the main question about how to retrieve the captured window dimensions remains open.
    Let me create an example for you I am in the office so I have to multitask
    A good exercise for the Heart is to bend down and help another up...
    Please Mark your Thread "Resolved", if the query is solved


    MyGear:
    ★ CPU ★ Ryzen 5 5800X
    ★ GPU ★ NVIDIA GeForce RTX 3080 TI Founder Edition
    ★ RAM ★ G. Skill Trident Z RGB 32GB 3600MHz
    ★ MB ★ ASUS TUF GAMING X570 (WI-FI) ATX Gaming
    ★ Storage ★ SSD SB-ROCKET-1TB + SEAGATE 2TB Barracuda IHD
    ★ Cooling ★ NOCTUA NH-D15 CHROMAX BLACK 140mm + 10 of Noctua NF-F12 PWM
    ★ PSU ★ ANTEC HCG-1000-EXTREME 1000 Watt 80 Plus Gold Fully Modular PSU
    ★ Case ★ LIAN LI PC-O11 DYNAMIC XL ROG (BLACK) (G99.O11DXL-X)
    ★ Monitor ★ LG Ultragear 27" 240Hz Gaming Monitor
    ★ Keyboard ★ TVS Electronics Gold Keyboard
    ★ Mouse ★ Logitech G502 Hero

  10. #10
    VB For Fun Edgemeal's Avatar
    Join Date
    Sep 2006
    Location
    WindowFromPoint
    Posts
    4,255

    Re: GetActiveWindow question

    Quote Originally Posted by krtxmrtz View Post
    the main question about how to retrieve the captured window dimensions remains open.
    dim rct as RECT
    GetWindowRect handle, rct

    Width = rct.right-rct.left
    Height = rct.bottom-rct.top

    EDIT Note those dimensions are in Pixels. Also when using BitBlt one normally uses ScaleWidth, ScaleHeight for pic boxes.
    Last edited by Edgemeal; Aug 30th, 2010 at 10:08 AM.

  11. #11

    Thread Starter
    vbuggy krtxmrtz's Avatar
    Join Date
    May 2002
    Location
    In a probability cloud
    Posts
    5,573

    Re: GetActiveWindow question

    Quote Originally Posted by Edgemeal View Post
    dim rct as RECT
    GetWindowRect handle, rct

    Width = rct.right-rct.left
    Height = rct.bottom-rct.top

    EDIT Note those dimensions are in Pixels. Also when using BitBlt one normally uses ScaleWidth, ScaleHeight for pic boxes.
    It's very strange that rct dimensions below are all returned as 0. I wonder what I may be overlooking.
    Code:
            hnd = GetDC(GetActiveWindow)
            GetWindowRect hnd , rct
            Picture1.Width = rct.Right - rct.Left
            Picture1.Height = rct.Bottom - rct.Top
    Lottery is a tax on people who are bad at maths
    If only mosquitoes sucked fat instead of blood...
    To do is to be (Descartes). To be is to do (Sartre). To be do be do (Sinatra)

  12. #12
    VB For Fun Edgemeal's Avatar
    Join Date
    Sep 2006
    Location
    WindowFromPoint
    Posts
    4,255

    Re: GetActiveWindow question

    Quote Originally Posted by krtxmrtz View Post
    It's very strange that rct dimensions below are all returned as 0. I wonder what I may be overlooking.
    Your passing the DC instead of the Window handle for GetWindowRect.


    Win_hWnd = GetActiveWindow
    GetWindowRect Win_hWnd , rct

  13. #13

    Thread Starter
    vbuggy krtxmrtz's Avatar
    Join Date
    May 2002
    Location
    In a probability cloud
    Posts
    5,573

    Re: GetActiveWindow question

    Quote Originally Posted by Edgemeal View Post
    Your passing the DC instead of the Window handle for GetWindowRect.


    Win_hWnd = GetActiveWindow
    GetWindowRect Win_hWnd , rct
    Thanks.

    Now it appears I was wrong, I thought GetActiveWindow would return the handle to any window I'd set the focus to (that's why I allowed a 2 second delay) but it fails, if I click on a different window from that of the app, it returns 0:
    VB Code:
    1. Dim hWnd As Long
    2.     Dim rct As RECT
    3.     '...
    4.     '(A delay function has been used to allow the
    5.     'user to click-select a different window)
    6.     '...
    7.     hWnd = GetActiveWindow
    8.     'hWnd is 0 !!!
    9.     GetWindowRect hWnd, rct
    Maybe GetActiveWindow is not the right function to be used !?
    Lottery is a tax on people who are bad at maths
    If only mosquitoes sucked fat instead of blood...
    To do is to be (Descartes). To be is to do (Sartre). To be do be do (Sinatra)

  14. #14
    Software Carpenter dee-u's Avatar
    Join Date
    Feb 2005
    Location
    Pinas
    Posts
    11,127

    Re: GetActiveWindow question

    You can try the GetForegroundWindow API.
    Regards,


    As a gesture of gratitude please consider rating helpful posts. c",)

    Some stuffs: Mouse Hotkey | Compress file using SQL Server! | WPF - Rounded Combobox | WPF - Notify Icon and Balloon | NetVerser - a WPF chatting system

  15. #15

    Thread Starter
    vbuggy krtxmrtz's Avatar
    Join Date
    May 2002
    Location
    In a probability cloud
    Posts
    5,573

    Re: GetActiveWindow question

    Quote Originally Posted by dee-u View Post
    You can try the GetForegroundWindow API.
    It works, but:

    1. It captures only the client area (no titlebar which I meant to include, though this could be left as a selectable option to the user)
    2. GetWindowRect returns the size including the titlebar so, the final captured image is the client area plus an extra bit of the desktop background at the bottom and right -the latter I don't understand, as there's no such thing as a titlebar or similar at the left
    VB Code:
    1. hWnd = GetForegroundWindow()
    2. GetWindowRect hWnd, rct
    3. ret = GetDC(hWnd)
    4. 'Form scalemode is twips, Tx and Ty are the screen twips per pixel x and y
    5. Picture1.Width = (rct.Right - rct.left) * Tx
    6. Picture1.Height = (rct.Bottom - rct.Top) * Ty
    7. Picture1.Cls
    8. BitBlt Picture1.hDC, 0, 0, Picture1.Width \ Tx, Picture1.Height \ Ty, ret, 0, 0, SRCCOPY
    Lottery is a tax on people who are bad at maths
    If only mosquitoes sucked fat instead of blood...
    To do is to be (Descartes). To be is to do (Sartre). To be do be do (Sinatra)

  16. #16
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: GetActiveWindow question

    GetDC does the client area. GetWindowDC does the entire window. May consider PrintWindow API?
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  17. #17

    Thread Starter
    vbuggy krtxmrtz's Avatar
    Join Date
    May 2002
    Location
    In a probability cloud
    Posts
    5,573

    Re: GetActiveWindow question

    Quote Originally Posted by LaVolpe View Post
    GetDC does the client area. GetWindowDC does the entire window. May consider PrintWindow API?
    Thanks for the clarification. Also, PrintWindow works satisfactorily:
    VB Code:
    1. 'This part works nicely
    2.         hWnd = GetForegroundWindow()
    3.         GetWindowRect hWnd, rct
    4.         ret = GetWindowDC(hWnd)
    5.         PicAux.Width = (rct.Right - rct.left) * Tx
    6.         PicAux.Height = (rct.Bottom - rct.Top) * Ty
    7.         PicAux.Cls
    8.         PrintWindow hWnd, PicAux.hDC, 0
    Now, if I only want the client area GetWindowRect does not yield the correct dimensions. Is there such a thing as GetWindowClientRect or similar?
    VB Code:
    1. '...but this doesn't
    2.         hWnd = GetForegroundWindow()        
    3.         GetWindowRect hWnd, rct
    4.         ret = GetDC(hWnd)
    5.         PicAux.Width = (rct.Right - rct.left) * Tx
    6.         PicAux.Height = (rct.Bottom - rct.Top) * Ty
    7.         PicAux.Cls
    8.         PrintWindow hWnd, PicAux.hDC, PW_CLIENTONLY
    Lottery is a tax on people who are bad at maths
    If only mosquitoes sucked fat instead of blood...
    To do is to be (Descartes). To be is to do (Sartre). To be do be do (Sinatra)

  18. #18
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: GetActiveWindow question

    Yes, GetClientRect. The left/top values will almost always be zero. So, if you need the client coordinates relative to the screen, you could use ClientToScreen API.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  19. #19

    Thread Starter
    vbuggy krtxmrtz's Avatar
    Join Date
    May 2002
    Location
    In a probability cloud
    Posts
    5,573

    Re: GetActiveWindow question

    Quote Originally Posted by LaVolpe View Post
    Yes, GetClientRect. The left/top values will almost always be zero. So, if you need the client coordinates relative to the screen, you could use ClientToScreen API.
    I know I'm a bit thickheaded, I can't figure out how to get the the proper metrics.
    VB Code:
    1. 'What's wrong with this code???
    2.         hwnd = GetForegroundWindow()
    3.         ret = GetDC(hwnd)
    4.         GetClientRect hwnd, rct
    5.         point.x = rct.Right - rct.left
    6.         point.y = rct.Bottom - rct.Top
    7.         ClientToScreen hwnd, point
    8.         PicAux.Width = point.x * Tx
    9.         PicAux.Height = point.y * Ty
    10.         PicAux.Cls
    11.         PrintWindow hwnd, PicAux.hDC, PW_CLIENTONLY
    I'm always getting captured images larger and even much larger then the original window. See the attached images: left, the (entire) window correctly captured with the code I included in my previous post, right, the wrongly captured client area.
    Attached Images Attached Images   
    Lottery is a tax on people who are bad at maths
    If only mosquitoes sucked fat instead of blood...
    To do is to be (Descartes). To be is to do (Sartre). To be do be do (Sinatra)

  20. #20
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: GetActiveWindow question

    Quote Originally Posted by krtxmrtz View Post
    I know I'm a bit thickheaded, I can't figure out how to get the the proper metrics.
    Since you are using the ClientRect for sizing purpopses, you don't need to mess with ClientToScreen. ClientToScreen is useful if you need to capture the client image from the desktop DC, but in this case not applicable.
    VB Code:
    1. hwnd = GetForegroundWindow()
    2. '        ret = GetDC(hwnd)
    3.         GetClientRect hwnd, rct
    4. '        point.x = rct.Right - rct.left
    5. '        point.y = rct.Bottom - rct.Top
    6. '        ClientToScreen hwnd, point
    7.         PicAux.Width = (rct.Right - rct.left) * Tx
    8.         PicAux.Height = ( rct.Bottom - rct.Top) * Ty
    9.         PicAux.Cls
    10.         PrintWindow hwnd, PicAux.hDC, PW_CLIENTONLY

    Note: If you use GetDC or GetWindowDC, you should use ReleaseDC also for each hDC you retrieve.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  21. #21

    Thread Starter
    vbuggy krtxmrtz's Avatar
    Join Date
    May 2002
    Location
    In a probability cloud
    Posts
    5,573

    Re: GetActiveWindow question

    Quote Originally Posted by LaVolpe View Post
    ...
    Note: If you use GetDC or GetWindowDC, you should use ReleaseDC also for each hDC you retrieve.
    Thanks, I'd forgotten about this.

    The picturebox seems to have the right size but it's the entire window that's captured, only it's offset. Attached, again, see the entire window and what should be the client area right below it.
    Attached Images Attached Images   
    Last edited by krtxmrtz; Sep 1st, 2010 at 02:06 PM.
    Lottery is a tax on people who are bad at maths
    If only mosquitoes sucked fat instead of blood...
    To do is to be (Descartes). To be is to do (Sartre). To be do be do (Sinatra)

  22. #22
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: GetActiveWindow question

    I see what your are talking about. Obviously the PW_CLIENTONLY flag does not work as expected
    I've seen other posts on the net similar to yours with no resolutions. I can think of a few workarounds:

    1. Don't use PrintWindow and
    a) do it the way your were before with GetDC/GetWindowDC
    b) Use SendMessage with WM_PRINT but doesn't work all the time, depends if window processes it
    c) Use SendMessage with WM_PAINT but doesn't work all the time, depends if window processes it

    2. Use PrintWindow (XP & above)
    If wanting just the client area, you will want to offset the DC before you call the API, then reset the offset. I trust you can find the API declarations
    Code:
        Dim pt As POINTAPI, rctW As RECT
        Dim theHwnd As Long
        
        theHwnd = &HAC03DC ' &H460450
        
        GetClientRect theHwnd, rctW
        
        ' size picturebox/destination DC. Note that picbox is borderless here
        Picture1.Move Picture1.Left, Picture1.Top, (rctW.Right - rctW.Left) * Screen.TwipsPerPixelX, (rctW.Bottom - rctW.Top) * Screen.TwipsPerPixelY
        
        pt.x = rctW.Left: pt.y = rctW.Top
        ClientToScreen theHwnd, pt          ' convert client coords to screen coords
        GetWindowRect theHwnd, rctW         ' get entire window dimensions
        pt.x = rctW.Left - pt.x             ' calculate offset of client rect to window rect
        pt.y = rctW.Top - pt.y
                                            ' offset DC, call PrintWindow, reset offset
        SetViewportOrgEx Picture1.hdc, pt.x, pt.y, pt
        PrintWindow theHwnd, Picture1.hdc, 0 ' do not use PW_CLIENTONLY
        SetViewportOrgEx Picture1.hdc, pt.x, pt.y, pt
    Note: If wanting the entire window, simply do not offset the DC & use GetWindowRect dimensions vs. GetClientRect
    Also note that thru some tests, PrintWindow will sometimes print the client in black! More research may be needed.
    Edited: Adding a DoEvents after resizing the picturebox seems to produce consistent results
    Edited Yet Again: Is this PrintWindow anamoly only applicable on themed windows? You may want to test that
    Last edited by LaVolpe; Sep 1st, 2010 at 10:48 PM.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  23. #23

    Thread Starter
    vbuggy krtxmrtz's Avatar
    Join Date
    May 2002
    Location
    In a probability cloud
    Posts
    5,573

    Re: GetActiveWindow question

    What are these constants?
    theHwnd = &HAC03DC ' &H460450

    GetClientRect theHwnd, rctW returns a rectangle with all zeros.

    However, if I place this statement at the very beginning,

    hWnd = GetForegroundWindow()

    then it works, except the resulting size is the maximum of all previously captured windows, see attached image. Also, as you point out, sometimes the captured window is black.

    The code for capturing the entire window works satisfactorily so, maybe it would be easier if the dimensions of the client area could be somehow calculated / retrieved. Then a BitBlt would easily do the trick.
    Attached Images Attached Images  
    Lottery is a tax on people who are bad at maths
    If only mosquitoes sucked fat instead of blood...
    To do is to be (Descartes). To be is to do (Sartre). To be do be do (Sinatra)

  24. #24

    Thread Starter
    vbuggy krtxmrtz's Avatar
    Join Date
    May 2002
    Location
    In a probability cloud
    Posts
    5,573

    Re: GetActiveWindow question

    Quote Originally Posted by Me
    ...
    ...if the dimensions of the client area could be somehow calculated / retrieved...
    Of course this would be immediate by substracting the coordinates produced by GetWindowRect and GetClientRect if the coordinates of the client area were relative to the upper left corner of the entire window. My question is, can it be assumed that the client area is horizontally centered, i.e. that the thicknesses of the left and right borders of the main window are the same? And as for the vertical corrdinates, I wonder if all that has to be done is substracting the height of the titlebar. Do the menus fall into the client area or not?
    Lottery is a tax on people who are bad at maths
    If only mosquitoes sucked fat instead of blood...
    To do is to be (Descartes). To be is to do (Sartre). To be do be do (Sinatra)

  25. #25

    Thread Starter
    vbuggy krtxmrtz's Avatar
    Join Date
    May 2002
    Location
    In a probability cloud
    Posts
    5,573

    Re: GetActiveWindow question

    So I did as I explained in my previous post and it finally worked:
    VB Code:
    1. 'Working code:
    2.         hwnd = GetForegroundWindow()
    3.         GetWindowRect hwnd, rctW
    4.         GetClientRect hwnd, rctC
    5.         Picture2.Width = (rctW.Right - rctW.left) * Screen.TwipsPerPixelX
    6.         Picture2.Height = (rctW.Bottom - rctW.Top) * Screen.TwipsPerPixelY
    7.         Picture2.Cls
    8.         PrintWindow hwnd, Picture2.hDC, 0    'Now Picture2 has the complete window
    9.         'x offset of client area = window border thickness
    10.         offx = (rctW.Right - rctW.left) - rctC.Right
    11.         offx = offx \ 2
    12.         'y offset for client area
    13.         offy = (rctW.Bottom - rctW.Top) - (rctC.Bottom + offx)
    14.         'Resize the destination picturebox to the client area
    15.         PicAux.Cls
    16.         PicAux.Width = rctC.Right * TwipsPerPixelX
    17.         PicAux.Height = rctC.Bottom * TwipsPerPixelY
    18.         'Copy the client area
    19.         BitBlt PicAux.hDC, 0, 0, sct.Right, sct.Bottom, Picture2.hDC, offx, offy, SRCCOPY
    ...only I had to use a second picturebox, because BitBlt'ing PicAux onto itself produced unwanted effects. It showed the correctly captured client area, but its Image property which I later use to save to a file (SavePicture instruction) couldn't be resized.
    Lottery is a tax on people who are bad at maths
    If only mosquitoes sucked fat instead of blood...
    To do is to be (Descartes). To be is to do (Sartre). To be do be do (Sinatra)

  26. #26
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: GetActiveWindow question

    Quote Originally Posted by krtxmrtz View Post
    What are these constants?
    theHwnd = &HAC03DC ' &H460450
    Just hWnds to test the code against, that's all. You would supply your valid hWnds, either hardcoded for testing or via a function that selects the window.
    Last edited by LaVolpe; Sep 2nd, 2010 at 08:55 AM.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  27. #27

    Thread Starter
    vbuggy krtxmrtz's Avatar
    Join Date
    May 2002
    Location
    In a probability cloud
    Posts
    5,573

    Re: [RESOLVED] GetActiveWindow question

    There must be tons of screen save applications and examples around, but since you guys (and other people from these forums some time ago) have been lending a hand I think I should post my work, which is a revision of an old project I already posted some time ago. Probably it can benefit from some makeup and refurbishing, especially in the save-to-file part, but here it is anyway.
    Attached Files Attached Files
    Last edited by krtxmrtz; Sep 7th, 2010 at 11:21 AM.
    Lottery is a tax on people who are bad at maths
    If only mosquitoes sucked fat instead of blood...
    To do is to be (Descartes). To be is to do (Sartre). To be do be do (Sinatra)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width