передача gdi хэндла в другой процесс (WM_PRINT)
От: Аноним  
Дата: 04.10.10 10:14
Оценка:
Привет всем.
Вопрос в сабже.

Поиск по форуму дал ветку http://rsdn.ru/forum/winapi/2865921.aspx
Автор: AndrewJD
Дата: 06.03.08
.
Все свелось к тому, что gdi хэндл нельзя передавать другому процессу, нужно передавать биты изображения и восстанавливать битмап в том же формате через CreateDIB... SetDIBBits...

Но
есть
WM_SETICON

— где передается HICON в другой процесс
также
WM_PRINT/PRINTCLIENT, PrintWindow

— где передается хендл HDC в другой процесс

Но все попытки организовать собственную передачу и обработку HDC в другой процесс отличную от WM_PRINT неудачны.

Хендл передается или через файл мэпинг или через WM_USER, в контексте ничего не рисуется. Вывод: стандартный обработчие WM_PRINT что то делает с преданным контектом.(?)

Может у кого есть мычли по этому вопросу?
winapi
Re: передача gdi хэндла в другой процесс (WM_PRINT)
От: Jolly Roger  
Дата: 04.10.10 10:46
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Но

А>есть
А>
А>WM_SETICON
А>

А>- где передается HICON в другой процесс
А>также
А>
А>WM_PRINT/PRINTCLIENT, PrintWindow
А>

А>- где передается хендл HDC в другой процесс

Некоторые сообщения система обрабатывет более сложно, чем просто передача идентификатора и параметров. Например, WM_COPYDATA использует MMF, ЕМНИП, чтобы передать массив байт между процессами. Вполне возможно, что и с указанными Вами сообщениями она поступает похожим образом.
"Нормальные герои всегда идут в обход!"
Re[2]: передача gdi хэндла в другой процесс (WM_PRINT)
От: Tyro  
Дата: 04.10.10 10:56
Оценка:
Здравствуйте, Jolly Roger, Вы писали:

JR>Здравствуйте, Аноним, Вы писали:


А>>Но

А>>есть
А>>
А>>WM_SETICON
А>>

А>>- где передается HICON в другой процесс
А>>также
А>>
А>>WM_PRINT/PRINTCLIENT, PrintWindow
А>>

А>>- где передается хендл HDC в другой процесс

JR>Некоторые сообщения система обрабатывет более сложно, чем просто передача идентификатора и параметров. Например, WM_COPYDATA использует MMF, ЕМНИП, чтобы передать массив байт между процессами. Вполне возможно, что и с указанными Вами сообщениями она поступает похожим образом.


Спасибо зо быстрый отклик.
С передачей массива байт и хендлами(не gdi) проблем нет.
Но возникла реальная потребность общего использования хэндла контекста.
Вобщем хотелось бы узнать, реально ли чтото раскопать по этому вопросу, как система обрабатывает переданные gdi хэндлы (для WM_SETICON, WM_PRINT)
Re: передача gdi хэндла в другой процесс (WM_PRINT)
От: Pavel Dvorkin Россия  
Дата: 04.10.10 11:31
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Поиск по форуму дал ветку http://rsdn.ru/forum/winapi/2865921.aspx
Автор: AndrewJD
Дата: 06.03.08
.

А>Все свелось к тому, что gdi хэндл нельзя передавать другому процессу, нужно передавать биты изображения и восстанавливать битмап в том же формате через CreateDIB... SetDIBBits...

Ну не так все мрачно. Есть CreateDIBSection, а хендл ее memory-mapped file (mmf) передать можно. Впрочем, можно и не передавать.

Вариант 1.

Процесс A создает mmf (CreateFileMapping) с NULL в качестве первого параметра и неким именем мэппинга, после чего вызывает CreateDIBSection и заносит туда биты.
Процесс B делает то же самое, только биты не заносит и имеет свой HBITMAP.

Вариант 2.
Процесс A создает mmf (CreateFileMapping) с NULL в качестве первого параметра и неким именем мэппинга, после чего вызывает CreateDIBSection и заносит туда биты.
Процесс A вызывает DuplicateHandle для хендла mmf и процесса B в качестве target-процесса, после чего этот дубликат-хендл передается в процесс B любым приемлемым способом.
Процесс вызывает CreateDIBSection по этому хендлу и имеет HBITMAP


А>Хендл передается или через файл мэпинг или через WM_USER, в контексте ничего не рисуется. Вывод: стандартный обработчие WM_PRINT что то делает с преданным контектом.(?)


А>Может у кого есть мычли по этому вопросу?


Jolly Roger все описал верно.
With best regards
Pavel Dvorkin
Re[2]: передача gdi хэндла в другой процесс (WM_PRINT)
От: Аноним  
Дата: 07.10.10 12:34
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Здравствуйте, Аноним, Вы писали:


А>>Поиск по форуму дал ветку http://rsdn.ru/forum/winapi/2865921.aspx
Автор: AndrewJD
Дата: 06.03.08
.

А>>Все свелось к тому, что gdi хэндл нельзя передавать другому процессу, нужно передавать биты изображения и восстанавливать битмап в том же формате через CreateDIB... SetDIBBits...

PD>Ну не так все мрачно. Есть CreateDIBSection, а хендл ее memory-mapped file (mmf) передать можно. Впрочем, можно и не передавать.


Если через файл мэпинг передавать биты изображения (тойже CreateDIBSection или полученные из CreateCompatibleBitmap) и восстанавливать их в другом процессе, то все работает. Но это долго гонять туда-обратно массив дольшой длины.

Если передавать именно хендл на DIBSection, то ничего не работает. Другой процесс как бы и "рисует" или модифицирует биты изображения через этот хэндл но исходный процесс не видит этого.
Re[2]: передача gdi хэндла в другой процесс (WM_PRINT)
От: Аноним  
Дата: 07.10.10 13:18
Оценка:
PD>Вариант 1.

PD>Процесс A создает mmf (CreateFileMapping) с NULL в качестве первого параметра и неким именем мэппинга, после чего вызывает CreateDIBSection и заносит туда биты.

PD>Процесс B делает то же самое, только биты не заносит и имеет свой HBITMAP.

PD>Вариант 2.

PD>Процесс A создает mmf (CreateFileMapping) с NULL в качестве первого параметра и неким именем мэппинга, после чего вызывает CreateDIBSection и заносит туда биты.
PD>Процесс A вызывает DuplicateHandle для хендла mmf и процесса B в качестве target-процесса, после чего этот дубликат-хендл передается в процесс B любым приемлемым способом.
PD>Процесс вызывает CreateDIBSection по этому хендлу и имеет HBITMAP

Спасибо за ответ.
Но немного туплю. Павел, вы имели в виду, что можно передать именно хэндл созданный через CreateDIBSection в другой процесс и в этом другом процессе будкт видны все биты изображения связанные с этим хэндлом?
Или привязать биты к mmf?

Опишу задачу в целом.

Есть изображение, которое модифицируется несколькими процессами. Отдельный процесс рисует свою часть изображения на основе анализа всего изображения, полученного ото всех процессов. С синхронизацией проблем нет. Хочется ускорить передачу изображения от одного процесса к другому.
Передавать биты изображения от одного процесс к другому долго(массив большой длины, размер в несколько экранов с высоким разрешением).
Передача хэндла контекста изображения или хэендла битмапа выглядит более привлекательно, но gdi хэндлы не передаются (передаваться то они предаются конечно, но толку от этого никакого, не работают в чужом процессе даже через DuplicateHandle). Как лучше организовать передачу изображения?
Re[3]: передача gdi хэндла в другой процесс (WM_PRINT)
От: Pavel Dvorkin Россия  
Дата: 07.10.10 14:15
Оценка:
Здравствуйте, Аноним, Вы писали:


А>Если через файл мэпинг передавать биты изображения (тойже CreateDIBSection


Да

>или полученные из CreateCompatibleBitmap)


Упаси боже

>и восстанавливать их в другом процессе, то все работает. Но это долго гонять туда-обратно массив дольшой длины.


В том-то и дело, что нет. Ни передавать, ни восстанавливать не надо.

Еще раз.

Процесс A

hMapping = CreateFileMapping(INVALID_HANDLE_VALUE,...,"UniqueName"); // можно GUID в качестве имени
hBitmap= CreateDIBSection(... &pBits, hMapping, 0);
// выбираем hBitmap в hdc
// рисуем на hBitmap любым способом — векторной графикой, BitBlt, ...
// не забудь когда-нибудь потом (не сейчас!) все закрыть и уничтожить.

Процесс B. Предполагается, что он будет делать нижеследующее после того, как процесс A сделал вышеприведенное

hMapping = CreateFileMapping(INVALID_HANDLE_VALUE,...,"UniqueName"); // то же самое имя
hBitmap= CreateDIBSection(... &pBits, hMapping, 0);
// выбираем hBitmap в hdc
// картинка к твоим услугам.
// не забудь когда-нибудь потом (не сейчас!) все закрыть и уничтожить.

If hSection is not NULL, the CreateDIBSection function locates the bitmap bit values at offset dwOffset in the file-mapping object referred to by hSection.


А>Если передавать именно хендл на DIBSection, то ничего не работает.


Хендл битмапа нельзя передавать. А вот hSection, если его открыть в обоих процессах, будет относиться к одному и тому же мэппингу. Кстати, передавать его непосредственно тоже нельзя, хотя и можно с помощью DuplicateHandle.

>Другой процесс как бы и "рисует" или модифицирует биты изображения через этот хэндл но исходный процесс не видит этого.


Правильно.
With best regards
Pavel Dvorkin
Re[4]: передача gdi хэндла в другой процесс (WM_PRINT)
От: Аноним  
Дата: 07.10.10 14:18
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Еще раз.


PD>Процесс A


PD>hMapping = CreateFileMapping(INVALID_HANDLE_VALUE,...,"UniqueName"); // можно GUID в качестве имени

PD>hBitmap= CreateDIBSection(... &pBits, hMapping, 0);
PD>// выбираем hBitmap в hdc
PD>// рисуем на hBitmap любым способом — векторной графикой, BitBlt, ...
PD>// не забудь когда-нибудь потом (не сейчас!) все закрыть и уничтожить.

PD>Процесс B. Предполагается, что он будет делать нижеследующее после того, как процесс A сделал вышеприведенное


PD>hMapping = CreateFileMapping(INVALID_HANDLE_VALUE,...,"UniqueName"); // то же самое имя

PD>hBitmap= CreateDIBSection(... &pBits, hMapping, 0);
PD>// выбираем hBitmap в hdc
PD>// картинка к твоим услугам.
PD>// не забудь когда-нибудь потом (не сейчас!) все закрыть и уничтожить.

PD>If hSection is not NULL, the CreateDIBSection function locates the bitmap bit values at offset dwOffset in the file-mapping object referred to by hSection.



Спасибо! Дошло.
CreateDIBSection(... &pBits, hMapping, 0);
Re[3]: передача gdi хэндла в другой процесс (WM_PRINT)
От: Pavel Dvorkin Россия  
Дата: 07.10.10 14:18
Оценка:
Здравствуйте, Аноним, Вы писали:

PD>>Вариант 1.


PD>>Процесс A создает mmf (CreateFileMapping) с NULL в качестве первого параметра и неким именем мэппинга, после чего вызывает CreateDIBSection и заносит туда биты.

PD>>Процесс B делает то же самое, только биты не заносит и имеет свой HBITMAP.

PD>>Вариант 2.

PD>>Процесс A создает mmf (CreateFileMapping) с NULL в качестве первого параметра и неким именем мэппинга, после чего вызывает CreateDIBSection и заносит туда биты.
PD>>Процесс A вызывает DuplicateHandle для хендла mmf и процесса B в качестве target-процесса, после чего этот дубликат-хендл передается в процесс B любым приемлемым способом.
PD>>Процесс вызывает CreateDIBSection по этому хендлу и имеет HBITMAP

А>Спасибо за ответ.

А>Но немного туплю. Павел, вы имели в виду, что можно передать именно хэндл созданный через CreateDIBSection в другой процесс и в этом другом процессе будкт видны все биты изображения связанные с этим хэндлом?
А>Или привязать биты к mmf?

А>Опишу задачу в целом.


А>Есть изображение, которое модифицируется несколькими процессами. Отдельный процесс рисует свою часть изображения на основе анализа всего изображения, полученного ото всех процессов. С синхронизацией проблем нет. Хочется ускорить передачу изображения от одного процесса к другому.

А>Передавать биты изображения от одного процесс к другому долго(массив большой длины, размер в несколько экранов с высоким разрешением).
А>Передача хэндла контекста изображения или хэендла битмапа выглядит более привлекательно, но gdi хэндлы не передаются (передаваться то они предаются конечно, но толку от этого никакого, не работают в чужом процессе даже через DuplicateHandle). Как лучше организовать передачу изображения?

Ответил тут, еще не прочитав это твое сообщение. Но там в ответе все есть. Если будут еще вопросы, задавай там.

http://rsdn.ru/forum/winapi/3988562.1.aspx
Автор: Pavel Dvorkin
Дата: 07.10.10
With best regards
Pavel Dvorkin
Re[4]: передача gdi хэндла в другой процесс (WM_PRINT)
От: Аноним  
Дата: 07.10.10 14:30
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Ответил тут, еще не прочитав это твое сообщение. Но там в ответе все есть. Если будут еще вопросы, задавай там.


PD>http://rsdn.ru/forum/winapi/3988562.1.aspx
Автор: Pavel Dvorkin
Дата: 07.10.10


Дошло. Спасибо еще раз.
Если смотреть в корень, то биты изображения помещаются в общую память или через mmf или shared section в dll.
По быстроте похоже одно и тоже, не считая инициализации этой общей памяти.
Re[5]: передача gdi хэндла в другой процесс (WM_PRINT)
От: Pavel Dvorkin Россия  
Дата: 07.10.10 15:03
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Дошло. Спасибо еще раз.

А>Если смотреть в корень, то биты изображения помещаются в общую память или через mmf или shared section в dll.

Если быть более точным, то эта память — либо общие для двух процессов страницы RAM, либо страницы, которые сейчас в своп-файле, но если их переведут в RAM — станут общими для двух процессов.

А>По быстроте похоже одно и тоже, не считая инициализации этой общей памяти.


Инициализировать общую память — никак не медленнее, чем приватную. Скорее наоборот — больше вероятность, что страницы будут в RAM, а не свопе — они двум процессам нужны.

shared секция — альтернатива mmf, но просто для данной задачи технически неудобно (размер ее устанавливается еще до запуска и т.д.)
With best regards
Pavel Dvorkin
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.