.
Все свелось к тому, что gdi хэндл нельзя передавать другому процессу, нужно передавать биты изображения и восстанавливать битмап в том же формате через CreateDIB... SetDIBBits...
Но
есть
WM_SETICON
— где передается HICON в другой процесс
также
WM_PRINT/PRINTCLIENT, PrintWindow
— где передается хендл HDC в другой процесс
Но все попытки организовать собственную передачу и обработку HDC в другой процесс отличную от WM_PRINT неудачны.
Хендл передается или через файл мэпинг или через WM_USER, в контексте ничего не рисуется. Вывод: стандартный обработчие WM_PRINT что то делает с преданным контектом.(?)
А>- где передается HICON в другой процесс А>также А>
А>WM_PRINT/PRINTCLIENT, PrintWindow
А>
А>- где передается хендл HDC в другой процесс
Некоторые сообщения система обрабатывет более сложно, чем просто передача идентификатора и параметров. Например, WM_COPYDATA использует MMF, ЕМНИП, чтобы передать массив байт между процессами. Вполне возможно, что и с указанными Вами сообщениями она поступает похожим образом.
"Нормальные герои всегда идут в обход!"
Re[2]: передача gdi хэндла в другой процесс (WM_PRINT)
Здравствуйте, 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)
. А>Все свелось к тому, что 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)
. А>>Все свелось к тому, что 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)
А>Если через файл мэпинг передавать биты изображения (тойже 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.
Здравствуйте, Аноним, Вы писали:
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[4]: передача gdi хэндла в другой процесс (WM_PRINT)
От:
Аноним
Дата:
07.10.10 14:30
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Ответил тут, еще не прочитав это твое сообщение. Но там в ответе все есть. Если будут еще вопросы, задавай там.
PD>http://rsdn.ru/forum/winapi/3988562.1.aspx
Дошло. Спасибо еще раз.
Если смотреть в корень, то биты изображения помещаются в общую память или через mmf или shared section в dll.
По быстроте похоже одно и тоже, не считая инициализации этой общей памяти.
Re[5]: передача gdi хэндла в другой процесс (WM_PRINT)
Здравствуйте, Аноним, Вы писали:
А>Дошло. Спасибо еще раз. А>Если смотреть в корень, то биты изображения помещаются в общую память или через mmf или shared section в dll.
Если быть более точным, то эта память — либо общие для двух процессов страницы RAM, либо страницы, которые сейчас в своп-файле, но если их переведут в RAM — станут общими для двух процессов.
А>По быстроте похоже одно и тоже, не считая инициализации этой общей памяти.
Инициализировать общую память — никак не медленнее, чем приватную. Скорее наоборот — больше вероятность, что страницы будут в RAM, а не свопе — они двум процессам нужны.
shared секция — альтернатива mmf, но просто для данной задачи технически неудобно (размер ее устанавливается еще до запуска и т.д.)