Здравствуйте, Schumann, Вы писали: S>Дык если тема не знакомая — то нифига и не понятно! Вот и прошу примерчик: как енто все сделать
Ты бы еще спросил "как писать игры для PC". Примера тут ни у кого видать нету.
Задай конкретный вопрос, на который можно ответить. Вон flax задает конкретные вопросы. А тебе что непонятно?
... << RSDN@Home 1.1 beta 2 >>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, jkris, Вы писали: J>а можно в неклиентской области менять Canvas, или ручками все прорисовывать?
Э-э, пардон, на что менять?
У вас в целом есть два выхода по отношению к неклиентской области (впрочем, как и к клиентской): либо полагаться на поведение оконной процедуры, предоставленной вам выбранным классом окна, либо перехватывать WM_NCPAINT и делать с ним все, что захочется (как с шоколадом Виспа).
... << RSDN@Home 1.1.0 stable >>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>Задай конкретный вопрос, на который можно ответить. Вон flax задает конкретные вопросы. А тебе что непонятно?
и еще — в чем лучше писать подобные приложения, просто на WinApi, либо в билдере, учитывая, что в требуемом приложении нужно будет очень много и часто работать с алгоритмами и визуальным представлением информации — картинками, матрицами и прочая?
как менять Hue(может плохо искал, но не нашел)? Или перерисовывать все окна, поменяв Hue у бэкграундов?
MaskBlt?
у KlipFolio высота заголовка окошек меньше стандартной. Как менять его размер? (перерисовать часть?)
Они оставляли заголовок (у главной части формы — не окошек, а там, где кнопочки закрыть/свернуть) и просто его перерисовали, либо они задавали стиль формы без границы и заголовка и сами все рисовали + обрабатывали события?
Остальные окошки — это отдельные формы, так?
(извиняюсь, если задаю глупые вопросы — для меня подобная тема нова и я только разбираюсь)
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, jkris, Вы писали: J>>а можно в неклиентской области менять Canvas, или ручками все прорисовывать? S>Э-э, пардон, на что менять?
Не канвас, а битмат, растягивая его как нужно при перерисовке(StretchBlt), меняя когда надо цвет(MaskBlt?).
S>У вас в целом есть два выхода по отношению к неклиентской области (впрочем, как и к клиентской): либо полагаться на поведение оконной процедуры, предоставленной вам выбранным классом окна, либо перехватывать WM_NCPAINT и делать с ним все, что захочется (как с шоколадом Виспа).
А что можно с ним сделать?
Как менять размер заголовка, например? Перерисовать не всю область не катит, она, как понял из опытов, все равно остается — просто не перерисовывается.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, jkris, Вы писали: J>>а можно в неклиентской области менять Canvas, или ручками все прорисовывать? S>Э-э, пардон, на что менять?
Если я правильно понял вопрос — спрашивается, можно ли использовать Canvas для неклиентской области.. отвечаю, да:
procedure TSkinnedForm.WMNCPaint(var Msg: TWMNCPaint);
var
Canvas: TCanvas;
ADC: HDC;
begin
Canvas := TCanvas.Create();
try
ADC := GetWindowDC(Handle);
Canvas.Handle := ADC;
// тут работаем с Canvas....
// В Canvas - ВСЯ форма, включая рамку и заголовок.
// Начало координат - не помню... но вроде бы в верхнем левом
// углу НЕКЛИЕНТСКОЙ части окнаfinally
Canvas.Handle := 0;
ReleaseDC(Handle, ADC);
end;
end;
... << RSDN@Home 1.1.2 beta 1 >>
Если при компиляции и исполнении вашей программы не происходит ни одной ошибки — это ошибка компилятора :)))
Здравствуйте, jkris, Вы писали: J>как менять Hue(может плохо искал, но не нашел)? Или перерисовывать все окна, поменяв Hue у бэкграундов? J>MaskBlt?
Не подойдет. Надо вручную пройтись по всем пикселам битмэпа и пересчитать значение цвета: RGB->HSV->H'SV->RGB. Естественно это делается один раз, при инициализации приложения (или смене настроек) J>у KlipFolio высота заголовка окошек меньше стандартной. Как менять его размер? (перерисовать часть?)
Есть такая мессага WM_NCCALCSIZE, если не ошибаюсь. Ее обработчик и определяет, какая часть окна клиентская, а какая нет.
Стоит отметить, что ничем сверхестественным неклиентская область от клиентской не отличается. Она была сделана для того, чтобы программист мог управлять внутренностями окна, отдавая стандартную часть поведения на откуп микрософту. Это позволило изменить список кнопок в заголовке при переходе Win3.1->Win95 и сделать градинетную заливку вместо монотонной в Win98. Если тебе не нужна похожесть на стандарт, то можно запросто сделать размер клиентской области совпадающим со всем окном и рисовать все там. J>Они оставляли заголовок (у главной части формы — не окошек, а там, где кнопочки закрыть/свернуть) и просто его перерисовали, либо они задавали стиль формы без границы и заголовка и сами все рисовали + обрабатывали события?
А черт его знает. В принципе, можно докопаться, но щачем? От этого зависят тольео мелкие детали реализации. J>Остальные окошки — это отдельные формы, так?
Скорее всего да. Это как правило проще, чем делать одно окно сложной формы (хотя и в этом есть некоторые преимущества). J>(извиняюсь, если задаю глупые вопросы — для меня подобная тема нова и я только разбираюсь)
Да ничего, разбирайся на здоровье
... << RSDN@Home 1.1.0 stable >>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Hacker_Delphi, Вы писали:
H_D>Если я правильно понял вопрос — спрашивается, можно ли использовать Canvas для неклиентской области.. отвечаю, да: H_D>[pascal] H_D>procedure TSkinnedForm.WMNCPaint(var Msg: TWMNCPaint);
Здравствуйте, Sinclair, Вы писали:
J>>как менять Hue(может плохо искал, но не нашел)? Или перерисовывать все окна, поменяв Hue у бэкграундов? J>>MaskBlt? S>Не подойдет. Надо вручную пройтись по всем пикселам битмэпа и пересчитать значение цвета: RGB->HSV->H'SV->RGB. Естественно это делается один раз, при инициализации приложения (или смене настроек)
COLORADJUSTMENT ?
пересчитывать в HSV как?
J>>у KlipFolio высота заголовка окошек меньше стандартной. Как менять его размер? (перерисовать часть?) S>Есть такая мессага WM_NCCALCSIZE, если не ошибаюсь. Ее обработчик и определяет, какая часть окна клиентская, а какая нет.
смотрю, пока не понял, как этим пользоваться
S> ... Если тебе не нужна похожесть на стандарт, то можно запросто сделать размер клиентской области совпадающим со всем окном и рисовать все там.
И обрабатывать события изменения размеров окна, его перемещения и т.п.?
J>>Они оставляли заголовок (у главной части формы — не окошек, а там, где кнопочки закрыть/свернуть) и просто его перерисовали, либо они задавали стиль формы без границы и заголовка и сами все рисовали + обрабатывали события? S>А черт его знает. В принципе, можно докопаться, но щачем? От этого зависят тольео мелкие детали реализации.
Если не оставлять заголовок и т.п. нужно обрабатывать нажатия кнопки мыши на области, которая обозначает заголовок и перемещения мыши вслед за этим — например. Не очень много, но писанина. Так?
Ну и смена курсора мыши когда мы перемещаем этот курсор к правой нижней области окна.
J>>(извиняюсь, если задаю глупые вопросы — для меня подобная тема нова и я только разбираюсь) S>Да ничего, разбирайся на здоровье
на счет вот этого кода..
H_D>Если я правильно понял вопрос — спрашивается, можно ли использовать Canvas для неклиентской области.. отвечаю, да:
H_D>procedure TSkinnedForm.WMNCPaint(var Msg: TWMNCPaint);
H_D>var
H_D> Canvas: TCanvas;
H_D> ADC: HDC;
H_D>begin
H_D> Canvas := TCanvas.Create();
H_D> try
H_D> ADC := GetWindowDC(Handle);
H_D> Canvas.Handle := ADC;
H_D> // тут работаем с Canvas....
H_D> // В Canvas - ВСЯ форма, включая рамку и заголовок.
H_D> // Начало координат - не помню... но вроде бы в верхнем левом
H_D> // углу НЕКЛИЕНТСКОЙ части окна
H_D> finally
H_D> Canvas.Handle := 0;
H_D> ReleaseDC(Handle, ADC);
H_D> end;
H_D>end;
H_D>
или то же на С++
void __fastcall TEditForm::FormPaint(TObject *Sender)
{
TCanvas *Canvas=new(TCanvas);
HDC ADC;
ADC = GetWindowDC(Handle);
Canvas->Handle = ADC;
// тут работаем с Canvas....
// В Canvas - ВСЯ форма, включая рамку и заголовок.
// Начало координат - не помню... но вроде бы в верхнем левом
// углу НЕКЛИЕНТСКОЙ части окна
Canvas->Draw(Width - Image1->Picture->Bitmap->Width, 0, Image1->Picture->Bitmap);
// пытаюсь вывести картинку в правом верхнем углу формы
// на форме также есть MainMenu и ControlBar (это важно!)
Canvas->Handle = 0;
ReleaseDC(Handle, ADC);
}
ну и что получается? во первых эта картинка "пропускает" клики. во вторых, жутко "моргает" при изменении размеров (может и пропасть). А если сделать все приложение из кусочков картинок??
И еще — вопрос. Есть ли возможность заблокировать отрисовку формы виндами, до тех пор, пока я полностью не отрисую форму (или не выполню какие-либо другие действия (например по нажатии кнопки состояние других компонент изменяется несколько раз) ?
PS: Вообще-то хочетца что-то вроде логотипа нарисовать поверх MainMenu и ControlBar и пр., и чтобы по клику на них оно не "проваливолось" под них, а остовалось все так же поверх.
Здравствуйте, DPP, Вы писали:
DPP>ну и что получается? во первых эта картинка "пропускает" клики. во вторых, жутко "моргает" при изменении размеров (может и пропасть). А если сделать все приложение из кусочков картинок??
DPP>И еще — вопрос. Есть ли возможность заблокировать отрисовку формы виндами, до тех пор, пока я полностью не отрисую форму (или не выполню какие-либо другие действия (например по нажатии кнопки состояние других компонент изменяется несколько раз) ?
DPP>PS: Вообще-то хочетца что-то вроде логотипа нарисовать поверх MainMenu и ControlBar и пр., и чтобы по клику на них оно не "проваливолось" под них, а остовалось все так же поверх.
Ну еще надо обрабатывать WM_NCACTIVATE, WM_NCMOUSEXXX и прочие WM_NCXXX — просто винда вместо вызова WM_NCPAINT при всяких событиях типа наведения мыши на кнопку в заголовке окна просто заново ее рисует — это надо перехватить, т.е. при проведении мышт надо отдавать обработку предку, а затем — перерисовыать ту часть, над которой мышь "проехала"... для этого еще и придется сохранять координаты мыши и таймеры — короче куча бодяги всякой...
Hint: для того, чтобы винда не рисовала всяких "лишних" кнопок — нужно при отлове сообщения WM_SETSTYLE (ыроде еще было WM_SETEXSTYLE) сохранять флаги, касающиеся заголовка и прочих "вкусностей" типа рамки у себя, а в предка отдавать без рамок.
потом — в WM_NCCALCSIZE считать клиентскую область.
а в WM_NCPAINT/WM_NCACTIVATE/WM_NCMOUSEXXX обрабатывать саму отрисовку, в том числе — и меню...
дальше — сам
... << RSDN@Home 1.1.2 beta 1 >>
Если при компиляции и исполнении вашей программы не происходит ни одной ошибки — это ошибка компилятора :)))
Здравствуй, jkris!
j> Как менять размер заголовка, например? Перерисовать не всю область j> не катит, она, как понял из опытов, все равно остается — просто не j> перерисовывается.
Менять динамически? Размер заголовка запрашивается только при создании
окна.
Поэтому, если вам хочется делать заголовок меняющимся, то вам нужно
создать окно без заголовка. Рисовать его самим как вам хочется и
обрабатывая WM_NCHITTEST говорить системе, что такая-то область — это
у нас заголовок.
--
Всего хорошего, Слава. (http://slava.users.otts.ru)
-= Пусть вон тот желтый кубик будет, для наглядности, синим шариком.
=-
Здравствуйте, jkris, Вы писали: J>>>как менять Hue(может плохо искал, но не нашел)? Или перерисовывать все окна, поменяв Hue у бэкграундов? J>>>MaskBlt? S>>Не подойдет. Надо вручную пройтись по всем пикселам битмэпа и пересчитать значение цвета: RGB->HSV->H'SV->RGB. Естественно это делается один раз, при инициализации приложения (или смене настроек)
J>COLORADJUSTMENT ?
Никакого отношения. J>пересчитывать в HSV как?
Поищи на RSDN по фразе "RGB to HSL". Был кусок кода. S>>Есть такая мессага WM_NCCALCSIZE, если не ошибаюсь. Ее обработчик и определяет, какая часть окна клиентская, а какая нет. J>смотрю, пока не понял, как этим пользоваться
А чего тут не понять? Тебе дали данные — ты в ответ сообщил, где тебе нужно иметь клиентскую зону. Все остальное считается неклиентской зоной. S>> ... Если тебе не нужна похожесть на стандарт, то можно запросто сделать размер клиентской области совпадающим со всем окном и рисовать все там. J>И обрабатывать события изменения размеров окна, его перемещения и т.п.? J>Если не оставлять заголовок и т.п. нужно обрабатывать нажатия кнопки мыши на области, которая обозначает заголовок и перемещения мыши вслед за этим — например. Не очень много, но писанина. Так?
Не обязательно. Достаточно обрабатывать WM_NCHITTEST. (Имея, конечно, ненулевую неклиентскую зону)
... << RSDN@Home 1.1.0 stable >>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>Не обязательно. Достаточно обрабатывать WM_NCHITTEST. (Имея, конечно, ненулевую неклиентскую зону)
Выделеное является полной ерундой...
вот такой код будет работать (есть форма, в которой лежит bvlCaption: TBevel с Align = alTop и у которой нет Border'а):
procedure TForm1.WMNCHitTest(var Msg: TWMNCHitTest);
begin
inherited;
if Msg.Result = HTCLIENT then
begin
if PtInRect(Bevel1.BoundsRect, ScreenToClient(Point(Msg.XPos, Msg.YPos))) then
Msg.Result := HTCAPTION;
end;
end;
Ремарки:
1. Нужен именно TBevel или другой non-Windowed Control, иначе обработка просто не дойдет до нас.
2. аккуратнее с расположением в этой области других подобных контролов (типа Speed Button) — для них не будет генерироваться мышиных сообщений... никаких.
... << RSDN@Home 1.1.2 beta 2 >>
Если при компиляции и исполнении вашей программы не происходит ни одной ошибки — это ошибка компилятора :)))
Здравствуйте, DPP, Вы писали:
DPP>...во вторых, жутко "моргает" при изменении размеров (может и пропасть). А если сделать все приложение из кусочков картинок??
А вы достаточно хорошо изучили механизм прорисовки окон в Windows? Надеюсь, не забыли, что помимо событий WM_PAINT, WM_NCPAINT происходит и WM_ERASEBACKGRND при котором окно обычно закрашивает себя определенным цветом. Проблема мелькания заключается в том, что сообщения стирания фона окна и его прорисовки отображают результат прямо на экране (а не, например, в буфере), поэтому при масштабировании окна у вас сначала закрашивается фон цветом окна, а уже затем вы получаете возможность прорисовки самого изображения. Выход, например, такой: проглатывать (игнорировать) все сообщения WM_ERASEBACKGRND, а стирать изображение (если это необходимо) в обработчиках WM_PAINT и WM_NCPAINT.