Что нового

Периодически из буфера вставляется не тот скрин и буфер не чистится

DyadyaGenya

Знающий
Сообщения
284
Репутация
8
Доброго времени суток. Заметил одну проблему. Функция вроде делает скрин, но не всегда показывает последний скрин. Иногда показывает тот, который был перед этим. Очистить буфер не получается. Оставил закоментированные строки чтобы показать, как пробовал чистить. Может не там ставил очистку и не так. В чем может быть проблема со показом последнего скрина и чисткой буфера?
Код:
#include <WinAPI.au3>
#include <WindowsConstants.au3>
#Include <ScreenCapture.au3>
#include <Clipboard.au3>

Global $Counter = IniRead("Setting.ini","Statistika","Count","0")
$Shell = ObjCreate('Shell.Application')
$Shell.NameSpace('куда').CopyHere('откуда', 16)
_SCREEN()
Func _SCREEN()
If Not WinExists("[class:OperationStatusWindow]") Then
    MsgBox(4096, 'Сообщение', 'Окно не найдено, завершаем работу скрипта')
    Exit
Else
    $hWnd = WinGetHandle("[CLASS:OperationStatusWindow]")
Send("!{PRINTSCREEN}")
_ClipBoard_Open(0)
$hBitmap = _ClipBoard_GetDataEx($CF_BITMAP)
;_ClipBoard_Empty()
;ClipPut("")
;_ClipBoard_SetDataEx("")
_ClipBoard_Close()
_GDIPlus_Startup()
$hImage = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap)
_GDIPlus_ImageSaveToFile($hImage, @ScriptDir & "\screen" & $Counter & ".bmp")
_GDIPlus_BitmapDispose($hImage)
_GDIPlus_Shutdown()
Dim $Screen = @ScriptDir & "\screen" & $Counter & ".bmp"
ShellExecute($Screen)
EndIf
EndFunc   ;==>_SCREEN

Пы.Сы. Пробовал делать зависимость от процентов на (99 или 100). Так скрин не всегда делается и тогда вызов картинки не происходит. Значит скрин делается, только непонятно куда.
 
Последнее редактирование:

joiner

Модератор
Локальный модератор
Сообщения
3,470
Репутация
609
Код:
#include <ScreenCapture.au3>

Local $sDirScreen = @ScriptDir & '\Screen\' & Random(1, 1000, 1) & '.bmp'
Local $Shell = ObjCreate('Shell.Application')
$Shell.NameSpace('куда').CopyHere('Откуда', 16)
_SCREEN($sDirScreen)
Func _SCREEN($sPath)
    Local $hWnd = WinGetHandle('[CLASS:OperationStatusWindow]')
    If @error Then
        Exit
    Else
        WinActivate($hWnd)
        _ScreenCapture_CaptureWnd($sPath, $hWnd)
        ShellExecute($sPath)
    EndIf
EndFunc   ;==>_SCREEN
 
Последнее редактирование:
Автор
D

DyadyaGenya

Знающий
Сообщения
284
Репутация
8
Спасибо. Это ты мне уже показывал. Я пояснял, что есть разница в качестве изображения, поэтому интересует в первую очередь именно мой способ, через клавиши "ПринтСкрин". Я его уже прикрутил к себе в форму. Только вот такой глюк вылазит регулярно, как в прикрученном виде, так и в изначальном
 

joiner

Модератор
Локальный модератор
Сообщения
3,470
Репутация
609
плохое качество? не вижу разницы
первое изображение сделано клавишей PrintScreen с клавиатуры , второе сделано кодом и вставлено в окно AutoIT


Безымянный.jpg

Безымянный.jpg
 

joiner

Модератор
Локальный модератор
Сообщения
3,470
Репутация
609
искажение происходит из за изменение размера или не пропорционально точного размера элемента Pic
само окно копирования всегда одного размера
пример ниже
Код:
#include <ScreenCapture.au3>
Global $Form1 = GUICreate("Form1", 800, 240, -1, -1)
Local $Pic1 = GUICtrlCreatePic("", 0, 0, 396, 114)
Local $Pic2 = GUICtrlCreatePic("", 396, 0, 396, 114)
Local $Pic3 = GUICtrlCreatePic("", 0, 114, 396, 114)
Local $Pic4 = GUICtrlCreatePic("", 396, 114, 396, 114)
GUISetState()
_SCREEN($Pic1, 1)
_SCREEN($Pic2, 2)
_SCREEN($Pic3, 3)
_SCREEN($Pic4, 4)

While 1
    Switch GUIGetMsg()
        Case -3
            Exit

    EndSwitch
WEnd

Func _SCREEN($iCtrl, $iCount)
    Local $sDirScreen = @ScriptDir & '\Screen_' & $iCount & '.jpg'
    Local $Shell = ObjCreate('Shell.Application')
    $Shell.NameSpace('Куда').CopyHere('Откуда', 16)
    Local $hWnd = WinGetHandle('[CLASS:OperationStatusWindow]')
    If Not @error Then
;~         WinSetOnTop($hWnd, '', 1) ;если нужна активация окна
        _ScreenCapture_CaptureWnd($sDirScreen, $hWnd, 26, 57, 421, 170, False)
        GUICtrlSetImage($iCtrl, $sDirScreen)
    EndIf
EndFunc   ;==>_SCREEN

результат работы кода на скрине
 

Вложения

  • Безымянный.jpg
    Безымянный.jpg
    53.3 КБ · Просмотры: 7
Последнее редактирование:
Автор
D

DyadyaGenya

Знающий
Сообщения
284
Репутация
8
искажение происходит из за изменение размера или не пропорционально точного размера элемента Pic
само окно копирования всегда одного размера
Размеры я старался подогнать пропорционально. Но в любом случае скрины твоей функцией делаются в формате bmp почти в два раза меньшего размера, когда делается моим способом. Я уже говорил об этом. И искажения не так сильно сказываются на читабельности. Ты сам говоришь, что окно самого скрина всегда одного размера. Значит и изменения при вставке одинаковые. Но в твоем случае читабельность уменьшается.
В том коде, что ты привел, растянуто вдоль, так сказать по горизонтали. Потому читабельность особо и не пострадала.
А вообще в этом варианте прикольно скринит, только саму область графика. Читабельность нормльаная. Только не могу решить, нужна ли дополнительная инфа из незаскринино1 части окошка.
 

joiner

Модератор
Локальный модератор
Сообщения
3,470
Репутация
609
в моем примере делается скрин части окна. ровно такой пропорции как и элемент Pic. куда будет вставляться скрин. в примере никакой растянутости нет. читабельность один к одному.
еще раз указываю на недостаток твоего варианта: использование системной клавиши скрина и использование буфера обмена.

вернусь к функции
Код:
_ScreenCapture_CaptureWnd

она, в совокупности, делает то же самое, что и в твоем коде, когда ты получаешь данные из буфера обмена - преобразует в файл скрина. можешь убедиться, открыв библиотеку ScreenCapture.au3
 
Последнее редактирование:
Автор
D

DyadyaGenya

Знающий
Сообщения
284
Репутация
8
она, в совокупности, делает то же самое, что и в твоем коде, когда ты получаешь данные из буфера обмена - преобразует в файл скрина
Да я понимаю, что она делает тоже самое. Но с другой стороны и размер файла другой.
И в любом случае интересно, почему в моем варианте периодически вставляется старая картинка. И даже иногда на ней зацикливается. Время то у меня уже позволяет возиться в мелочах и нюансах. Тем более, что буфер не чиститься, не обнуляется.
А про растянутость, вернее, что её нет, понял чуто позже, когда дошло, что заскринина только часть с графиком, а не все окно
 
Последнее редактирование:

joiner

Модератор
Локальный модератор
Сообщения
3,470
Репутация
609
размер файла меньше потому, что возвращается скрин не всего окна

буфер нужно чистить до скрина. то есть, до команды
Код:
Send("!{PRINTSCREEN}")

старые данные могут быть в буфере из-за того что не сработал Send
 
Последнее редактирование:
Автор
D

DyadyaGenya

Знающий
Сообщения
284
Репутация
8
буфер нужно чистить до скрина. то есть, до команды
Сработало.
размер файла меньше потому, что возвращается скрин не всего окна
Да, но если смотреть скрин, то он одинакового размера по ширине и высоте.
разрешение мое.jpgразрешение joiner.jpg
старые данные могут быть в буфере из-за того что не сработал Send
Вроде стал чиститься.
А почему, если я вставляю только первый тренировачный скрин только в первую ячейку, то он срабатывает всегда, даже если 50 раз подряд, а вот если дописываю код чтоб вставлял потом по очереди во все ячейки, то видимо Send не всегда срабатывает? Мне тут можно ж этот отрывок показать? По идее это все касается того, что из буфера вставляется не тот скрин.
 
Последнее редактирование:

joiner

Модератор
Локальный модератор
Сообщения
3,470
Репутация
609
в моем примере скрин получается 396х114
точно по размеру элемента Pic
насчет буфера обмена. у меня самого все это работает через раз. библиотека буфера обмена больше рассчитана на работу с буфером приложения
 
Автор
D

DyadyaGenya

Знающий
Сообщения
284
Репутация
8
в моем примере скрин получается 396х114
точно по размеру элемента Pic
Я говорю о том скрине, когда делается скрин всего окошка копирования, а не самого графика. И, кстати, в ходе экспериментов, были сдвиги скрина, захватывало не ту часть окошка. Вот, как один из примеров
образец обрезки.jpg
у меня самого все это работает через раз.
Не совсем понял. В твоем варианте через раз работает? Вроде не успел такого заметить. Реально по сто раз запускал твой вариант и ни разу не пропустило.
библиотека буфера обмена больше рассчитана на работу с буфером приложения
Так а разве мы не с буфером приложения работаем? И возможно я не прав, но почему то ж все срабатывает, если я делаю один скрин и вставляю его только в одну ячейку без механизма вставки в другие ячейки. И срабатывает 50 раз подряд. Срабатываение видно по изменившемуся скрину. Механизм у меня связан с $Counter, тоесть счетчиком нажатий на кнопку "Старт". Причем заметил, что в одном варианте вставляет только во 2 и 4 ячейки, а в другом варианте в 1 и 3. Есть ещё парочка модификаций, но там пропускает в одном случае первую ячейку, а в других уже не помню, но тоже была закономерность.
 

joiner

Модератор
Локальный модератор
Сообщения
3,470
Репутация
609
"через раз" это я про буфер обмена через кнопку скрин.
мой вариант тоже иногда дает сбой. не получается первый скрин. редко, но бывает.
 

InnI

AutoIT Гуру
Сообщения
4,740
Репутация
1,360
если смотреть скрин, то он одинакового размера
А если смотреть внимательно, то можно увидеть разную глубину цвета.

видимо Send не всегда срабатывает?
Возможно, но маловероятно. Скорее всего проблема в том, что данные в буфер обмена не помещаются мгновенно. Добавьте Sleep после Send порядка 100 или 200. А лучше 500.
 
Автор
D

DyadyaGenya

Знающий
Сообщения
284
Репутация
8
А если смотреть внимательно, то можно увидеть разную глубину цвета
Не присматривался, но это поясняет разницу в читабельности при вставке. И это опять поднимает вопрос о том, что клавишей ПринтСкрин сам скрин получается лучше.
Сразу поставил 500. Вроде 10 циклов прошли нормально ) Погоняю ещё и если у самого не получиться, то приду за более коротким кодом )
 

InnI

AutoIT Гуру
Сообщения
4,740
Репутация
1,360
И это опять поднимает вопрос о том, что клавишей ПринтСкрин сам скрин получается лучше.
Код:
#include <ScreenCapture.au3>

_ScreenCapture_CaptureWnd("24.bmp", WinGetHandle(""))
$__g_iBMPFormat = $GDIP_PXF32ARGB
_ScreenCapture_CaptureWnd("32.bmp", WinGetHandle(""))
 
Верх