powered by simpleCommunicator - 2.0.52     © 2025 Programmizd 02
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / В скриншот экрана попадает не всё
14 сообщений из 14, страница 1 из 1
В скриншот экрана попадает не всё
    #36754881
Guest v.22
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Примеров скриншота в нете множество, как сделать скриншот.
Например, самый простой:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
Private Sub Command1_Click()
    Dim Pt( 0  To  2 ) As POINTAPI
    Pt( 0 ).x =  0 
    Pt( 0 ).y =  0 
    Pt( 1 ).x = Screen.Width /  15 
    Pt( 1 ).y =  0 
    Pt( 2 ).x =  0 
    Pt( 2 ).y = Screen.Height /  15 
    PlgBlt Me.hDC, Pt( 0 ), GetDC( 0 ),  0 ,  0 , _
    Screen.Width / Screen.TwipsPerPixelX, Screen.Height / Screen.TwipsPerPixelY, _
    ByVal  0 &, ByVal  0 &, ByVal  0 &
End Sub

Проблема в том, что в скриншот не попадают окна, имеющие _расширенный_ стиль, например, полупрозначные.
Всякие красивые часики, квипы и т.п.
Вот такая форма не попадает:
Код: plaintext
1.
2.
3.
    Ret = GetWindowLong(Me.hwnd, GWL_EXSTYLE)
    Ret = Ret Or WS_EX_LAYERED
    SetWindowLong Me.hwnd, GWL_EXSTYLE, Ret
    SetLayeredWindowAttributes Me.hwnd,  0 ,  127 , LWA_ALPHA

Как можно сделать полный скриншот?
Ведь по кнопке Принтскрин, к примеру, в буфер обмена попадает нормальная картинка, значит, это как-то можно реализовать?
Без эмуляции нажатия принтскина и засорения буфера :))
...
Рейтинг: 0 / 0
В скриншот экрана попадает не всё
    #36754893
Фотография Konst_One
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Me.hwnd - это hwnd вашего окна, оно кэпчурится. замените его на хэндлер окна десктопа
...
Рейтинг: 0 / 0
В скриншот экрана попадает не всё
    #36754896
Фотография Konst_One
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Konst_OneMe.hwnd - это hwnd вашего окна, оно кэпчурится. замените его на хэндлер окна десктопа

стоп, не в тему. с прозрачностью не в курсе
...
Рейтинг: 0 / 0
В скриншот экрана попадает не всё
    #36755164
Фотография Игорь Горбонос
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
> Автор: Guest v.22
> >>> PlgBlt <<< Me.hDC, Pt(0), GetDC(0), 0, 0, _

Может воспользоватся BitBlt???

Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
В скриншот экрана попадает не всё
    #36755414
ak787
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вот, сделал 2 функции, самому потом пригодятся

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
Private Declare Sub keybd_event Lib "user32" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long)
Private Declare Function OpenClipboard Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function EmptyClipboard Lib "user32" () As Long
Private Declare Function CloseClipboard Lib "user32" () As Long
Private Declare Function IsClipboardFormatAvailable Lib "user32" (ByVal wFormat As Integer) As Long

Sub PrintScreenToFile(filePath)
    'очищаем
    OpenClipboard ( 0 &)
    EmptyClipboard
    CloseClipboard
    'делаем "print screen"
    Call keybd_event(&H2C,  0 ,  0 ,  0 )
    While IsClipboardFormatAvailable( 2 ) =  0 
      'ждем, пока появится снимок
      DoEvents
    Wend
    SavePicture Clipboard.GetData(vbCFBitmap), filePath
    'очищаем перед выходом
    OpenClipboard ( 0 &)
    EmptyClipboard
    CloseClipboard
End Sub

Sub PrintScreenToPictureBox(pic As PictureBox)
    'очищаем
    OpenClipboard ( 0 &)
    EmptyClipboard
    CloseClipboard
    'делаем "print screen"
    Call keybd_event(&H2C,  0 ,  0 ,  0 )
    While IsClipboardFormatAvailable( 2 ) =  0 
      'ждем, пока появится снимок
      DoEvents
    Wend
     pic.Picture = Clipboard.GetData(vbCFBitmap)
    'очищаем перед выходом
    OpenClipboard ( 0 &)
    EmptyClipboard
    CloseClipboard
End Sub

Private Sub Command1_Click()
PrintScreenToFile "e:\clip.bmp"
PrintScreenToPictureBox Me.Picture1
End Sub
...
Рейтинг: 0 / 0
В скриншот экрана попадает не всё
    #36755430
ak787
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Guest v.22
Без эмуляции нажатия принтскина и засорения буфера :))

в предыдущем посте я как раз эмулировал нажатие принтскрин и буфер потом очищается, но ты можешь сделать сохранение и востановление буфера
...
Рейтинг: 0 / 0
В скриншот экрана попадает не всё
    #36755455
ak787
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ну а если хочешь без засорения буфера, то вот

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
Private Declare Function CreateCompatibleDC Lib "GDI32" ( _
   ByVal hDC As Long) As Long
Private Declare Function CreateCompatibleBitmap Lib "GDI32" ( _
   ByVal hDC As Long, ByVal nWidth As Long, _
   ByVal nHeight As Long) As Long
Private Declare Function GetDeviceCaps Lib "GDI32" ( _
   ByVal hDC As Long, ByVal iCapabilitiy As Long) As Long
Private Declare Function GetSystemPaletteEntries Lib "GDI32" ( _
   ByVal hDC As Long, ByVal wStartIndex As Long, _
   ByVal wNumEntries As Long, lpPaletteEntries As PALETTEENTRY) _
   As Long
Private Declare Function CreatePalette Lib "GDI32" ( _
   lpLogPalette As LOGPALETTE) As Long
Private Declare Function SelectObject Lib "GDI32" ( _
   ByVal hDC As Long, ByVal hObject As Long) As Long
Private Declare Function BitBlt Lib "GDI32" ( _
   ByVal hDCDest As Long, ByVal XDest As Long, _
   ByVal YDest As Long, ByVal nWidth As Long, _
   ByVal nHeight As Long, ByVal hDCSrc As Long, _
   ByVal XSrc As Long, ByVal YSrc As Long, ByVal dwRop As Long) _
   As Long
Private Declare Function DeleteDC Lib "GDI32" ( _
   ByVal hDC As Long) As Long
Private Declare Function GetForegroundWindow Lib "USER32" () _
   As Long
Private Declare Function SelectPalette Lib "GDI32" ( _
   ByVal hDC As Long, ByVal hPalette As Long, _
   ByVal bForceBackground As Long) As Long
Private Declare Function RealizePalette Lib "GDI32" ( _
   ByVal hDC As Long) As Long
Private Declare Function GetWindowDC Lib "USER32" ( _
   ByVal hWnd As Long) As Long
Private Declare Function GetDC Lib "USER32" ( _
   ByVal hWnd As Long) As Long
Private Declare Function ReleaseDC Lib "USER32" ( _
   ByVal hWnd As Long, ByVal hDC As Long) As Long
Private Declare Function GetDesktopWindow Lib "USER32" () As Long
Private Declare Function OleCreatePictureIndirect _
   Lib "olepro32.dll" (PicDesc As PicBmp, RefIID As GUID, _
   ByVal fPictureOwnsHandle As Long, IPic As IPicture) As Long

Private Type PALETTEENTRY
    peRed As Byte
    peGreen As Byte
    peBlue As Byte
    peFlags As Byte
End Type

Private Type LOGPALETTE
   palVersion As Integer
   palNumEntries As Integer
   palPalEntry( 255 ) As PALETTEENTRY  ' Enough for 256 colors.
End Type

Private Type PicBmp
    Size As Long
    Type As Long
    hBmp As Long
    hPal As Long
    Reserved As Long
End Type

Private Type GUID
    Data1 As Long
    Data2 As Integer
    Data3 As Integer
    Data4( 7 ) As Byte
End Type
      
Public Function CaptureWindow(ByVal hWndSrc As Long, _
        ByVal Client As Boolean, ByVal LeftSrc As Long, _
        ByVal TopSrc As Long, ByVal WidthSrc As Long, _
        ByVal HeightSrc As Long) As Picture

        Dim hDCMemory As Long
        Dim hBmp As Long
        Dim hBmpPrev As Long
        Dim r As Long
        Dim hDCSrc As Long
        Dim hPal As Long
        Dim hPalPrev As Long
        Dim RasterCapsScrn As Long
        Dim HasPaletteScrn As Long
        Dim PaletteSizeScrn As Long
        Dim LogPal As LOGPALETTE

         ' Depending on the value of Client get the proper device context.
         If Client Then
            hDCSrc = GetDC(hWndSrc) ' Get device context for client area.
         Else
            hDCSrc = GetWindowDC(hWndSrc) ' Get device context for entire
                                          ' window.
         End If

         ' Create a memory device context for the copy process.
         hDCMemory = CreateCompatibleDC(hDCSrc)
         ' Create a bitmap and place it in the memory DC.
         hBmp = CreateCompatibleBitmap(hDCSrc, WidthSrc, HeightSrc)
         hBmpPrev = SelectObject(hDCMemory, hBmp)

         ' Get screen properties.
         RasterCapsScrn = GetDeviceCaps(hDCSrc, RASTERCAPS) ' Raster
                                                            ' capabilities.
         HasPaletteScrn = RasterCapsScrn And RC_PALETTE       ' Palette
                                                              ' support.
         PaletteSizeScrn = GetDeviceCaps(hDCSrc, SIZEPALETTE) ' Size of
                                                              ' palette.

         ' If the screen has a palette make a copy and realize it.
         If HasPaletteScrn And (PaletteSizeScrn =  256 ) Then
            ' Create a copy of the system palette.
            LogPal.palVersion = &H300
            LogPal.palNumEntries =  256 
            r = GetSystemPaletteEntries(hDCSrc,  0 ,  256 , _
                LogPal.palPalEntry( 0 ))
            hPal = CreatePalette(LogPal)
            ' Select the new palette into the memory DC and realize it.
            hPalPrev = SelectPalette(hDCMemory, hPal,  0 )
            r = RealizePalette(hDCMemory)
         End If

         ' Copy the on-screen image into the memory DC.
         r = BitBlt(hDCMemory,  0 ,  0 , WidthSrc, HeightSrc, hDCSrc, _
            LeftSrc, TopSrc, vbSrcCopy)

      ' Remove the new copy of the  on-screen image.
         hBmp = SelectObject(hDCMemory, hBmpPrev)

         ' If the screen has a palette get back the palette that was
         ' selected in previously.
         If HasPaletteScrn And (PaletteSizeScrn =  256 ) Then
            hPal = SelectPalette(hDCMemory, hPalPrev,  0 )
         End If

         ' Release the device context resources back to the system.
         r = DeleteDC(hDCMemory)
         r = ReleaseDC(hWndSrc, hDCSrc)

         ' Call CreateBitmapPicture to create a picture object from the
         ' bitmap and palette handles. Then return the resulting picture
         ' object.
         Set CaptureWindow = CreateBitmapPicture(hBmp, hPal)
End Function


Public Function CreateBitmapPicture(ByVal hBmp As Long, _
        ByVal hPal As Long) As Picture
        Dim r As Long
     
         Dim Pic As PicBmp
         ' IPicture requires a reference to "Standard OLE Types."
         Dim IPic As IPicture
         Dim IID_IDispatch As GUID

         ' Fill in with IDispatch Interface ID.
         With IID_IDispatch
            .Data1 = &H20400
            .Data4( 0 ) = &HC0
            .Data4( 7 ) = &H46
         End With

         ' Fill Pic with necessary parts.
         With Pic
            .Size = Len(Pic)          ' Length of structure.
            .Type = vbPicTypeBitmap   ' Type of Picture (bitmap).
            .hBmp = hBmp              ' Handle to bitmap.
            .hPal = hPal              ' Handle to palette (may be null).
         End With

         ' Create Picture object.
         r = OleCreatePictureIndirect(Pic, IID_IDispatch,  1 , IPic)

         ' Return the new Picture object.
         Set CreateBitmapPicture = IPic
      End Function

Public Function CaptureScreen() As Picture
        Dim hWndScreen As Long
         
         ' Get a handle to the desktop window.
         hWndScreen = GetDesktopWindow()

         ' Call CaptureWindow to capture the entire desktop give the handle
         ' and return the resulting Picture object.

         Set CaptureScreen = CaptureWindow(hWndScreen, False,  0 ,  0 , _
            Screen.Width \ Screen.TwipsPerPixelX, _
            Screen.Height \ Screen.TwipsPerPixelY)
End Function

Private Sub Command1_Click()
Me.Picture1.Picture = CaptureScreen
End Sub
...
Рейтинг: 0 / 0
В скриншот экрана попадает не всё
    #36755463
ak787
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
блин засада, поторопился, не проверил)) такой здоровый код из msdn да еще и не "снимает" формы типа SetWindowLong Me.hwnd, GWL_EXSTYLE, Ret .... бррр
...
Рейтинг: 0 / 0
В скриншот экрана попадает не всё
    #36756711
Guest v.22
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Игорь Горбонос,
Пробовал BitBlt - тоже самое.

ak787,
Жалко, что не получилось... с кнопкой принтскрина возиться не хочется, да и не гламурно как-то :)

... Мне кажется, что засада тут: GetDC(0).
Причем, если пробовать с GetDC(GetDesktopWindow), то результат получается такой же, хотя у меня GetDesktopWindow отлично от нуля.
Может, есть еще какое какое окно, о котором знает только виндоус, и GetDC с которого даёт нужный результат?
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
В скриншот экрана попадает не всё
    #38742618
Guest v.22
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
Private Sub Command1_Click()
    Dim Pt(0 To 2) As POINTAPI
    Pt(0).x = 0
    Pt(0).y = 0
    Pt(1).x = Screen.Width / 15
    Pt(1).y = 0
    Pt(2).x = 0
    Pt(2).y = Screen.Height / 15
    PlgBlt Me.hDC, Pt(0), GetDC(0), 0, 0, _
    Screen.Width / Screen.TwipsPerPixelX, Screen.Height / Screen.TwipsPerPixelY, _
    ByVal 0&, ByVal 0&, ByVal 0&
End Sub



В продолжение к теме. Возникла задача снять скриншот со второго экрана на системе с двумя мониторами.
Как?!
Есть подозрение, что GetDC(0) надо заменить на GetDC(другое) .
Пробовал через EnumDisplayMonitors выловить это другое , но не смог даже "0" для первого монитора выловить.

Если кто знает, что надо делать или видел ссылку на рабочий пример скриншота со второго монитора, буду благодарен.
Спасибо.
...
Рейтинг: 0 / 0
В скриншот экрана попадает не всё
    #38743575
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Guest v.22Есть подозрение, что GetDC(0) надо заменить на GetDC(другое) .dc у всех мониторов один, просто за счет дополнительных мониторов у него расширены координаты. если основной монитор правый, то дополнительная часть оси x будет отрицательна.
...
Рейтинг: 0 / 0
В скриншот экрана попадает не всё
    #38744004
Guest v.22
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Antonariy,

Понятно, спасибо.
Т.е. надо выловить координаты "полного" экрана и поменять соответствующие величины в PlgBlt?
Как бы их узнать?
...
Рейтинг: 0 / 0
В скриншот экрана попадает не всё
    #38744020
Guest v.22
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Аа, полный экран можно через GetSystemMetrics выловить.
Осталось узнать координаты каждого отдельного экрана.
...
Рейтинг: 0 / 0
В скриншот экрана попадает не всё
    #38744333
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я это однажды делал, забыл, но там все просто. EnumDisplayMonitors + еще какая-то функция.
...
Рейтинг: 0 / 0
14 сообщений из 14, страница 1 из 1
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / В скриншот экрана попадает не всё
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]