![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Проблема с созданием окна(CreateWindow) в отдельном потоке
sc0rp © (2009-03-24 10:10:00)Здравствуйте. Возникла следующая проблема с фунцией CreateWindow:
в основном приложении создается новая форма в одтельном потоке
TProcessForm.Process_Show(self,'test',Image1.Picture.Bitmap);
for I := 0 to 10 do
begin
sleep(100);
end;
TProcessForm.Process_Show(self,'test',Image1.Picture.Bitmap) создает эту форму.
код создания формы:
wc.cbSize:=sizeof(wc);
wc.style:=cs_hredraw or cs_vredraw;
wc.lpfnWndProc:=@WindowProc;
wc.cbClsExtra:=0;
wc.cbWndExtra:=0;
wc.hInstance:=HInstance;
wc.hIcon:=LoadIcon(0,idi_application);
wc.hCursor:=LoadCursor(0,idc_arrow);
wc.hbrBackground:=COLOR_BTNFACE+1;
wc.lpszMenuName:=nil;
wc.lpszClassName:='WinMin : Main';
RegisterClassEx(wc);
........
MainWnd:=CreateWindow( 'WinMin : Main',
'Win Min',
wS_POPUP or WS_DLGFRAME,
xPos,
yPos ,
nWidth,
nHeight,
//0,
HWNDparent,
0,
Hinstance,
nil
);
........
InvalidateRect(MainWnd,nil,false);
ShowWindow(MainWnd,CmdShow);
UpdateWindow(MainWnd);
Проблема в следующем: если HWNDparent<>0(тоесть создавать дочернюю форму)то при выполнении ShowWindow(MainWnd,CmdShow) управление передается из потока в основное приложение на выполнение цикла и только после завершения цикла поток продолжает работу, выполняет ShowWindow(MainWnd,CmdShow),UpdateWindow(MainWnd) и отображает созданное окно.Если создавать главное окно(HWNDparent=0) все работает нормально, окно создается параллельно работе основного приложения. В чем может быть причина? Мне нужно именно дочернее окно.
Slym (2009-03-29 12:06:00) [1]для нормального функционирования окна нужно обеспечить обработку мессаджей...
чтото типа
while GetMessage do DispatchMessage
sniknik (2009-03-28 11:41:00) [2]> покопавшись в интернете вы найдете подобное решение для подобной проблемы.
проблема у тебя, а копаться ему? :))) раз решение есть, и ты его видел, то просто его выполни. чего спрашивать то?
> переделывать весь комплекс не вариант.
если в основе извращенная логика (а судя по описанию так и есть), то вариантов то как раз и нет, это единственный верный путь. переделывать.
скажите спасибо тому кто заложил такую основу.
в нормальном варианте за интерфейс отвечает основной поток, а вот работу, длительные операции выносят в потоки. никак не наоборот.
sc0rp (2009-03-28 11:02:00) [3]Уважаемый Мастер Германн:
во первых вы ошибаетесь
> Ну тогда ты первопроходец!
покопавшись в интернете вы найдете подобное решение для подобной проблемы.
во вторых, если вам объяснение причин поможет ответить на поставленный вопрос, то объясняю. Большой программный комплекс, работает с бд. Много запросов на выполнение хранимых процедур. Изначально это окно было сделано с использованием VCL и при выполнении хранимой процедуры(может занимать много времени) vcl-ная форма подвисала, ожидая ответа от сервера. Обращение к серверу было реализовано на BDE,часть уже переведено на ado c асинхронным выполнением запроса, большинство осталось без изменения. Создание окна в отдельном потоке позволяет решить проблему подвисания.
> Вот когда доппоток создаётся для выполнения каких-то длительных
> процессов, а основной поток показывает, что приложение не
> подвисло, это вполне естественный вариант.
переделывать весь комплекс не вариант.
Германн (2009-03-28 01:05:00) [4]
> sc0rp (28.03.09 00:38) [10]
>
>
> > А тут всё наоборот?
>
> Именно. Все наоборот. На то есть свои причины.
>
Ну тогда ты первопроходец!
Вперёд с песнями. Если что-то получится, сообщи. Похлопочем о выдвижении твоего решения на нобеля (ну или хотя бы шнобеля :).
P.S. Ну а "свои причины" равно как и собственно задачу скрываем.
Партизаны никогда не выдают свои ноухау! :)
sc0rp (2009-03-28 00:38:00) [5]
> А тут всё наоборот?
Именно. Все наоборот. На то есть свои причины.
Германн (2009-03-28 00:24:00) [6]
> Окно ,создаваемое в отдельном потоке, показывает, что приложение
> выполняет какую-либо процедуру(это может быть обращение
> к бд на выполнение хранимой процедуры, обработка даных внутри
> циклов).
Смахивает на бред.
Вот когда доппоток создаётся для выполнения каких-то длительных процессов, а основной поток показывает, что приложение не подвисло, это вполне естественный вариант. А тут всё наоборот?
sc0rp (2009-03-27 23:49:00) [7]Уважаемые мастера, для самых умных и остроумных поясню. Это фрагмент тестового проекта. Окно ,создаваемое в отдельном потоке, показывает, что приложение выполняет какую-либо процедуру(это может быть обращение к бд на выполнение хранимой процедуры, обработка даных внутри циклов). Цикл,в данном случае эмулирует подобную деятельность. Попробую обьяснить более доходчиво.
основное приложении вызывается
TProcessForm.Process_Show(self,'test',Image1.Picture.Bitmap);
и продолжает свою работу.
Process_Show создает новое окно в отдельном потоке, которое показывает,что основное приложение не висит а что-то делает. создание этого окна по-моему показано достаточно полно. Еще раз описываю проблему.
Поток нормально начинает работать параллельно с основным приложением, но в момент выполненияShowWindow(MainWnd,CmdShow);(CmdShow:=WS_SHOWNORMAL) если HWNDparent<>0 управление предается в основное приложение, выполнение потока прерывается, и только после того, как приложение завершит свою работу(в данном случае цикл), поток продолжает выполнение и отображает окно. Есть какие-то конструктивные предложения по этому поводу?
P.S.
> напомнило "как индусские программисты узнают завтрашнюю
> дату:
> Sleep(24*60*60*1000);
> TomorrowDate := Date;
с таким остроумием срочно в аншлаг.
clickmaker (2009-03-27 14:10:00) [8]> for I := 0 to 10 do
> begin
> sleep(100);
> end;
напомнило "как индусские программисты узнают завтрашнюю дату:
Sleep(24*60*60*1000);
TomorrowDate := Date;
brother (2009-03-27 08:46:00) [9]> for I := 0 to 10 do
> begin
> sleep(100);
> end;
ну, напиши вместо всего этого sleep(1000), может поможет?)
Сергей М. (2009-03-27 08:41:00) [10]А что это за бестолковыйцикл ?
Где он размещен и для каких целей ?
sc0rp (2009-03-26 22:45:00) [11]
> Какого цикла ?
for I := 0 to 10 do
begin
sleep(100);
end;
Сергей М. (2009-03-24 15:59:00) [12]
> управление передается из потока в основное приложение на
> выполнение цикла
Какого цикла ?
sc0rp (2009-03-24 15:38:00) [13]
>
> > В чем может быть причина?
>
>
> В том что доч.окно создано в другом потоке
>
это я понял. а как это победить?
Сергей М. (2009-03-24 12:33:00) [14]
> В чем может быть причина?
В том что доч.окно создано в другом потоке