Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Компоненты";
Текущий архив: 2005.12.18;
Скачать: [xml.tar.bz2];

Вниз

Фрейм, PaintBox и клавиатура...   Найти похожие ветки 

 
tunguss ©   (2005-05-20 18:05) [0]

Вот есть вопрос к вам, уважаемые господа.

Описываю ситуацию.

Есть фрейм (он обязателен по умолчанию - без него никуда :) ) - разрабатывается отдельно, но тестируется на форме. Наследник фрейма, естественно.

Я положил в свое время на него PaintBox во всю ширь (это важно) чтобы рисовать по канвасу без каких-либо заморочек (об этой я еще тогда не знал :) ). Возможно именно тогда я ошибся и следовало бы создавать канвас в ран-тайме - сейчас это возможное решение, но, как вы понимаете, не желательное (не то что это трудно переделать, но существует опасность возникновения побочных проблем).

Итак. Проблема жутко тривиальная - фрейму не поймать нажатые клавиши. Все. Причем с мышью все в порядке (она как раз ловится PaintBox"ом).

Форма их принимать не может, потому что тогда проект не будет соответствовать спецификации. Все способы с хуками, переопределениями KeyDown и поимкой messag"ей - перепробованы.

Вполне логично предположить, что PaintBox берет на себя эти самые messag"ы. Но у PaintBox"а нет ивентов-обрабочиков клавиатуры!

Вот так. Прошу высказывать возможные решения проблемы. Поскольку есть вероятность, что для ее решения требуются минимальные усилия, которые либо просто не приходят в голову либо сказывается недостаток опыта :)


 
jack128 ©   (2005-05-21 17:19) [1]

tunguss ©   (20.05.05 18:05)
Вполне логично предположить, что PaintBox берет на себя эти самые messag"ы.

нет, не логично. PaintBox - наследник GraphicControl"а и сообщения от клавы не принемает. А фрейм не принимает на себя обработку начатия клавиш, так как он не имеет фокуса ввода. В отличии от всяких Edit"ов, Memo и тд фрейм при клике по нему не получает фокуса, так что это нужно делать самостоятельно.

type
 TFrame2 = class(TFrame)
   PaintBox1: TPaintBox;
   procedure PaintBox1Click(Sender: TObject);
 private
   procedure FrameKeyPress(Sender: TObject; var Key: Char);
   { Private declarations }
 public
   { Public declarations }
 end;

implementation

{$R *.dfm}

procedure TFrame2.FrameKeyPress(Sender: TObject; var Key: Char);
begin
 ShowMessage("Yra");
end;

procedure TFrame2.PaintBox1Click(Sender: TObject);
begin
 OnKeyPress := FrameKeyPress;
 if CanFocus then
   SetFocus;
end;


 
tunguss ©   (2005-05-23 12:46) [2]

По поводу наследования абсолютно согласен. Действительно, не логично :). Поторопился :).

Но... Ваш метод к сожалению не работает. Я его уже пробовал раньше (уже не перечислить сколько методов я пробовал :) ), но на всякий случай попробовал еще раз. Немного смутило название процедуры PaintBox1Click, но ради эксперимента попробовал даже с
ней :) (первым дело конечно же поставил это дело в конструктор).

KeyPreview у формы установлен в False, но, собственно, и со значением True фрейм абсолютно также упрямится :). ActiveControl на форме - тот самый фрейм. Но другие компоненты, тем не менее, независимо ни от KeyPreviiew, ни от ActiveControl, реагируют на нажатия клавиш так, как если бы фрейма вообще не было.

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

В любом случае, благодарю вас за внимание к моей проблеме.


 
VladimirB ©   (2005-05-23 16:29) [3]

TFrame2 = class(TFrame)
   PaintBox1: TPaintBox;
   procedure PaintBox1Click(Sender: TObject);
 private
   { Private declarations }
   procedure WMCharQ(var Message: TWMChar); message WM_CHAR;
  public
   { Public declarations }
 end;

implementation

{$R *.dfm}

procedure TFrame2.WMCharQ(var Message: TWMChar);
begin
ShowMessage("sdfsd");
end;

procedure TFrame2.PaintBox1Click(Sender: TObject);
begin
SetFocus;
end;

А это форма использующая фрейм.
type
 TForm1 = class(TForm)
   Frame21: TFrame2;
   Memo1: TMemo;
   procedure FormShow(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormShow(Sender: TObject);
begin
Frame21.SetFocus;
end;


 
tunguss ©   (2005-05-23 16:43) [4]

Попробовал. И так не прошло :(. Спасибо вам ребята за помощь но такое чувство что действительно где-то то ли в моем коде то ли в коде заказчика делается какая-то гадость (нет, в конструкторе формы я оспасных свойств не устанавливаю :)).

На всякий случай уточню, что мне нужен WM_KEYDOWN, поскольку я перехватываю нажатие стрелок - навигация и все такое.


 
jack128 ©   (2005-05-24 00:26) [5]

tunguss ©   (23.05.05 12:46) [2]
Немного смутило название процедуры PaintBox1Click, но ради эксперимента попробовал даже с
ней :)

Чем оно тебя смутило?? Автотматом генерируемое название обработчика события OnClick для компонента с именем PaintBox1. С высокой долей вероятности - этот компонент имеет тип TPaintBox. Короче

Unit1

dfm

object Form1: TForm1
 Left = 192
 Top = 107
 Width = 696
 Height = 480
 Caption = "Form1"
 Color = clBtnFace
 Font.Charset = DEFAULT_CHARSET
 Font.Color = clWindowText
 Font.Height = -11
 Font.Name = "MS Sans Serif"
 Font.Style = []
 OldCreateOrder = False
 PixelsPerInch = 96
 TextHeight = 13
 inline Frame21: TFrame2
   Left = 112
   Top = 80
   Width = 320
   Height = 240
   TabOrder = 0
 end
end


pas

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, Unit2;

type
 TForm1 = class(TForm)
   Frame21: TFrame2;
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

end.


Unit2

dfm

object Frame2: TFrame2
 Left = 0
 Top = 0
 Width = 320
 Height = 240
 TabOrder = 0
 object PaintBox1: TPaintBox
   Left = 0
   Top = 0
   Width = 320
   Height = 240
   Align = alClient
   OnClick = PaintBox1Click
 end
end


pas

unit Unit2;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, ExtCtrls;

type
 TFrame2 = class(TFrame)
   PaintBox1: TPaintBox;
   procedure PaintBox1Click(Sender: TObject);
 private
   procedure FrameKeyPress(Sender: TObject; var Key: Char);
   { Private declarations }
 public
   { Public declarations }
 end;

implementation

{$R *.dfm}

procedure TFrame2.FrameKeyPress(Sender: TObject; var Key: Char);
begin
ShowMessage("Yra");
end;

procedure TFrame2.PaintBox1Click(Sender: TObject);
begin
OnKeyPress := FrameKeyPress;
if CanFocus then
  SetFocus;
end;

end.


 
tunguss ©   (2005-05-24 14:07) [6]

Смутило тем, что чтобы фрейм получил фокус нужно тыкнуть в него мышкой :). Это метод когда на форме много контролов - пока так и есть - но в результирующей проге их не будет. Просто смутило. Не возмутило, не разозлило, ни чего еще подобное :)).


 
tunguss ©   (2005-05-24 14:09) [7]

Да, все приведенные примеры /отдельно/ от программы работают. Но не работают у меня в программе :). Все еще ищу хорошо укрывшуюся багу.


 
tunguss ©   (2005-05-26 15:31) [8]

Всем-всем-всем, кто сюда наткнется. Вероятно обнаружена бага в 6-7 дельфях (насчет других не знаю). Что делаем. Создаем фрейм и биндим ему OnKeyDown. В обработчике пишем что-нибудь вроде "Key catched". Кидаем фрейм на палитру и затем на пустую форму (необязательный шаг - можно и в рантайме его...).  Запускаем. Тыркаем буквенные клавиши. Все пойманы - хорошо. Тыкаем какую-нибудь стрелку. Упс - не поймало. Тыкаем буквенные клавиши.... Упс -.... тоже не поймало! А KeyDown должен ловить все!... Вот так. У кого есть доводы против того, что это бага и пути ее решения без правки кода формы (AppEvents ни на фрейме ни на форме тоже нежелателен) - пишите пожалуйста.


 
jack128 ©   (2005-05-26 17:17) [9]

проверять лениво, но скорее всего просто при нажатии стрелки фокус сместился с фрейма на какой то другой контрол...


 
rOOse ©   (2005-05-26 17:35) [10]

Дело в том что когда ты нажимаешь левуй(правую,вниз,вверх) фокус теряется т.е он переходит с фрейма на другой компонент или на саму форму
ты попробуй вместо стрелок поставить Enter or Escape (попробуй кинь на форму две кнопки одна над другой и keydown одной из них попробуй поймать стрелку вниз хрен получится)


 
tunguss ©   (2005-05-26 17:49) [11]

> to jack128:

 а если на форме нет контролов? :) (см. to rOOse)

> to rOOse:

 не должен фокус переходить на форму. Запусти допустим Settings > Control Panel > Mouse (чтобы был достойный пример задавших такие правила) и пожамкай на Tab. Перешел хоть раз фокус на форму? :) Теперь потыркай стрелочки. В разных разделах. Перешел фокус? :) И даже если так - перед потерей фокуса должна пойматься хотя бы последняя клавиша.


 
tunguss ©   (2005-05-26 17:51) [12]

безысходность это всегда баг. А тут нет выхода :). Поймать стрелочки. По крайней мере я его не вижу, а смотрел растопырив все глаза.


 
rOOse ©   (2005-05-26 18:05) [13]

ну не на форму но фокус теряется это точно


 
tunguss ©   (2005-05-26 18:10) [14]

абсолютно согласен - но КУДА :)))) ?????? И как его поймать-то :)))... KeyPreview к стрелочкам не относится. SetFocus, как видишь, не пашет. Можно было бы ловить стрелочку и принудительно возвращать фокус контролу - но ее не поймать, да и это некрасиво как-то. В багах ничего плохого - просто лучше чтобы о них где-то было объявлено чтобы проггеры могли сказать заказчику "извините, вот зайдите на borland.com и посмотрите - это баг, так что уж просим не винить нас, что мы извращаемся по-всякому чтобы его обойти"...


 
rOOse ©   (2005-05-26 18:16) [15]

кто помнит скан коды или ASCII клавиш?


 
tunguss ©   (2005-05-26 18:22) [16]

это к чему? :)


 
rOOse ©   (2005-05-26 18:23) [17]

а ты заметил что ctrl shift f1-f12 etc тоже не работают


 
tunguss ©   (2005-05-26 19:13) [18]

не заметил. ну ведь значит точно баг :). читаем хелп:

The OnKeyDown handler can respond to all keyboard keys, including function keys and keys combined with the Shift, Alt, and Ctrl keys, and pressed mouse buttons.

Круто, да? :)


 
rOOse ©   (2005-05-26 19:24) [19]

надо поробовать создать свой компонент на основе  TFrame и попробовать там


 
tunguss ©   (2005-05-26 19:27) [20]

может в чат пойдем :)) ?. а то все мои идеи уже теряются куда-то :)). я там :)


 
tunguss ©   (2005-05-26 19:27) [21]

может в чат пойдем :)) ?. а то все мои идеи уже теряются куда-то :)). я там :)


 
Юрий Зотов ©   (2005-05-27 10:48) [22]

> tunguss

На всякий случай загляните сюда, вдруг поможет:
http://delphimaster.net/view/5-1109751986/


 
tunguss ©   (2005-05-30 12:00) [23]

тема насчет бага все еще открыта. вышеочначенный флуд не считается - к решению мы не пришли :(.


 
tunguss ©   (2005-05-30 12:05) [24]

[22] к флуду естественно не относится, спасибо Юрий. Но к сожалению в данном случае предложенный там выход нам не позволен заказчиком :).


 
tunguss ©   (2005-05-30 12:31) [25]

вот эти две темы также относятся к означенной проблеме:

http://delphimaster.net/view/5-1109751986/
http://delphimaster.net/view/5-1109751986/


 
tunguss ©   (2005-05-30 14:21) [26]

УРА. Все. Тема закрыта. Делаем так:

protected
...
procedure WMGetDlgCode (var msg: TMessage); message WM_GETDLGCODE;
...

implementation

procedure TMyCustomControl.WMGetDlgCode(var msg: TMessage);
begin
inherited;
msg.Result := msg.Result + DLGC_WANTARROWS
end;


Покорнейше благодарю Юрия Зотова и Просто Джо.

P.S. Тема-то закрыта, но мы-то все равно знаем, что это баг /:))))


 
tunguss ©   (2005-05-30 14:23) [27]

P.P.S. и не пугайтесь слова Custom в этом примере, как сделал это я - это делается для наследников TWinControl, Custom-компоненты, как мы помним, делают это сами ::).


 
tunguss ©   (2005-05-30 15:49) [28]

И еще благодарю rOOSe, VladimirB - за проявление интереса к сему вопросу....

...прям как фильм снял :).



Страницы: 1 вся ветка

Форум: "Компоненты";
Текущий архив: 2005.12.18;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.57 MB
Время: 0.015 c
2-1133393751
Юрий Ж.
2005-12-01 02:35
2005.12.18
[?]TClientSocket & TServerSocket


14-1133098896
Alexis
2005-11-27 16:41
2005.12.18
На borland.com только Delphi 2005 .NET?


14-1132859236
Вероника
2005-11-24 22:07
2005.12.18
книги


6-1125765758
Nekt0
2005-09-03 20:42
2005.12.18
SMTP Авторизация на mail.ru


4-1128592123
Windows1
2005-10-06 13:48
2005.12.18
фокус на кнопке+нажать ее Enter^ом





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский