YURSHAT
Advanced Member | Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору VicF1 Если тебя интересует более подробно как работает ботва, могу написать в общих чертах (South рассказывал). Думаю будет полезно всем пользователям этой прекрасной dll. Итак начнем: ImgApplyChanges нужно вызывать после всех телодвижений с картинками. например в InitializeWizard Код: ImgLoad(h,ExpandConstant('{tmp}\WizardImage.jpg'),0,0,WizardForm.ClientWidth,WizardForm.ClientHeight,True,True); ImgLoad(h,ExpandConstant('{tmp}\l4d.jpg'),0,0,WizardForm.ClientWidth,WizardForm.ClientHeight,True,True); img1=ImgLoad(h,ExpandConstant('{tmp}\Panel2.png'),0,t,0,0,False,False); | Нарисовали, все эти картинки находятся в памяти, на экране вы их не увидите, теперь чтобы из всего этого составить слоеный пирог и вывести его на экран нужно вызвать ImgApplyChanges(WizardForm.Handle) или, например, в CurPageChanged if CurPageID=wpWelcome then begin ImgSetVisibility(img1,False); ImgRelease(img2) ImgSetPosition(img3,100,0,0,0); end; Сами по себе эти действия выполнятся очень быстро (в отличии от старых версий), но на экране изменений вы не увидите. Опять же для этого нужно вызвать ImgApplyChanges(WizardForm.Handle) I. Вывод изображения на экран У нас имеются 2 картинки в памяти: первая - слой (BkgImg), который рисуется под тем, что рисует инно (картинки с IsBkg=True), вторая - слой (FrontImg), который рисуется поверх всего (картинки с IsBkg=False) перед выводом изображения на экран целиковая картинка собирается в памяти: 1. стирается фон цветом формы 2. рисуется наш фоновый слой (BkgImg) 3. вызов оригинальной оконной процедуры визардформ с просьбой нарисовать себя в памяти поверх BkgImg 4. ну и вывод нашего верхнего слоя (FrontImg) 5. только потом, когда имеем цельную картинку, все это выводится одним махом на экран II. ImgApplyChanges Теперь представим, что вы просто сдвинули (ImgSetPosition) одну маленькую картинку нарисованную на фоне (IsBkg=True) на 10 пикселей. казалось бы фигня. А если подумать, то, чтобы форма могла нормально нарисоваться нам нужно переделать фоновый слой (BkgImg), который используется для вывода окончательного изображения на экран, т.е. нам нужно 1. стереть, то что было на фоновом слое (BkgImg) 2. затем нарисовать в BkgImg все картинки с флагом IsBkg=True (представьте, что у вас таких картинок штук 40-50) 3. оповестить наши кнопки, которые попали в изменяемую область о том, что у них изменится фон 4. отобразить все изменения на экране (заставить обновится окно), т.е. повторить все что было в I а если вы поработали с картинками из двух слоев - верхнего и нижнего, то добавятся еще два пункта 2.1. стереть, то что было в верхнем слое 2.2. нарисовать в FrontImg все картинки с флагом IsBkg=False В продолжение: Сами по себе ImgSetPosition и ImgSetVisibility ничего сверхестественного не делают просто запоминают в каком месте должна быть выведена (если Visible=True естественно) картинка, при этом не пересобирают слои, поэтому работают очень быстро. ImgRelease работает чуть дольше, т.к. ей еще нужно освободить память от загруженной картинки, но также не пересобирает слои ImgLoad загружает картинку в память и сохраняет параметры, которые в ней передали, опять же не собирает слои заново. Все эти процедуры также запоминают область (прямоугольник в координатах окна UpdateRect) где произошли изменения. Вобщем ничего сверхестественного, работать все это будет очень быстро. по крайней мере ImgSetPosition и ImgSetVisibility можно вызывать пачками, на скорости работы не должно сильно сказаться. Это как на форме с настройками программы. Вы меняете настройки (ставите нужные чекбоксы, выбираете нужные элементы из списка, в эдиты пишете что нужно) и ничего не изменится пока вы не нажмете кнопку "применить". Зато когда ее нажмешь можно ждать несколько секунд пока устанавливаются новые параметры. Так вот ImgApplyChanges и есть та самая кнопка "применить". Кратко о прогрессБаре Код: PBOldProc:=SetWindowLong(WizardForm.ProgressGauge.Handle,-4,CallBackProc(@PBProc,4)); | при этом ничего криминального в своей процедуре не делаем. Всегда вызываем оригинальный обработчик Код: Result:=CallWindowProc(PBOldProc,h,Msg,wParam,lParam); | чтобы ProgressGauge вел себя как обычно, без изменений. Но, если пришло сообщение что нашему WizardForm.ProgressGauge нужно изменить позицию, т.е. где-то присходит WizardForm.ProgressGauge.Position:=xx, то ловим это событие Код: и сдвигаем свой рисованный прогрессбар, считаем оставшееся время, проценты. т.е. рисованный прогрессбар сдвигается сразу после того как сдвинулся WizardForm.ProgressGauge и пока это не произойдет (сдвинется, посчитеатся, нарисуется) распаковка файлов дальше не пойдет. Что касается Код: то ту все просто - $2=WM_DESTROY. Это сообщение приходит, когда окно должно бы разрушено, но перед самим событием. Перед тем как окно уничтожается, правила хорошего тона требуют вернуть оригинальную оконную процедуру окна на место, что мы собственно и делаем Код: SetWindowLong(h,-4,PBOldProc); |
| Всего записей: 857 | Зарегистр. 07-11-2009 | Отправлено: 22:23 28-04-2010 | Исправлено: YURSHAT, 23:03 28-04-2010 |
|