powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Не работают стрелки в ActiveX (C++Builder)
1 сообщений из 1, страница 1 из 1
Не работают стрелки в ActiveX (C++Builder)
    #32239863
slydiman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
На C++Builder написал ActiveX (разновидность TEdit, точнее TRxCalcEdit лежащий на TActiveForn). При его загрузке в IE не работают стрелки и Backspace.

У Microsoft на этот счет есть Article 180402 и 168777:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
   // Trap keys and forward on to the control. 
   BOOL CMyEditCtrl::PreTranslateMessage(MSG* pMsg) 
   { 
      switch (pMsg->message) 
      { 
         case WM_KEYDOWN: 
         case WM_KEYUP: 
            switch (pMsg->wParam) 
            { 
               case VK_UP: 
               case VK_DOWN: 
               case VK_LEFT: 
               case VK_RIGHT: 
               case VK_HOME: 
               case VK_END: 
                  SendMessage (pMsg->message, pMsg->wParam, pMsg->lParam); 
                  // Windowless controls won't be able to call SendMessage. 
                  // Instead, just respond to the message here. 
                  return TRUE; 
            } 
            break; 
      } 
      return COleControl::PreTranslateMessage(pMsg); 
   }  


Еще встречал такое предложение:
Код: plaintext
1.
2.
3.
4.
LRESULT CMyCtrl::OnGetDlgCode(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) 
{ 
    return (DefWindowProc(uMsg, wParam, lParam) | DLGC_WANTALLKEYS | DLGC_WANTARROWS | DLGC_WANTCHARS | DLGC_WANTMESSAGE); 
}  


Простенькие эксперименты показали что сообщения о нажатии кнопок до TActiveForm не доходят.

Посмотрел


сделал свой класс TRxCalcEditX на основе TRxCalcEdit, где перехватил WndProc:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
  void __fastcall WndProc(Messages::TMessage &Message) 
  { 
    switch( Message.Msg ){ 
    case WM_GETDLGCODE: 
      Message.Result = DLGC_WANTALLKEYS | DLGC_WANTARROWS | DLGC_WANTMESSAGE | DLGC_WANTCHARS; 
    return; 
    case WM_KEYDOWN: 
    case WM_KEYUP: 
      switch( Message.WParam ){ 
      case VK_LEFT: 
      case VK_RIGHT: 
      case VK_HOME: 
      case VK_END: 
      case VK_BACK: 
        Message.Result = CallWindowProc( (WNDPROC)DefWndProc, Handle, Message.Msg, Message.WParam, Message.LParam ); 
      break; 
      } 
    break; 
    } 
    TRxCalcEdit::WndProc( Message ); 
  }; 


Оказывается сообщения WM_KEYDOWN о нажатии стрелок прекрасно доходят до TRxCalcEditX, но не обрабатываются, то есть курсор не перемещается!!!

Вызов родного обработчика через
Код: plaintext
1.
CallWindowProc( (WNDPROC)DefWndProc, Handle, Message.Msg, Message.WParam, Message.LParam ); 

не дает никаких результатов.

Если уменьшить окно Internet Explorer'а чтобы появилась прокрутка, то при нажатии стрелок содержимое окна IE прокручивается еще до вызова моего WndProc в TRxCalcEditX.

Пришлось применить хуки и поколдовать чтобы можно было загружать несколько одинаковых ActiveX объектов в одном окне:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
HHOOK hh = NULL; 
long hc =  0 ; 
 
LRESULT __stdcall GetMsgProc( int code, WPARAM wParam, LPARAM lParam ) 
{ 
  if( code >=  0  ){ 
    LPMSG pMsg = (LPMSG)lParam; 
    switch( pMsg->message ){ 
    case WM_KEYDOWN: 
    case WM_KEYUP: 
      switch( pMsg->wParam ){ 
      case VK_LEFT: 
      case VK_RIGHT: 
      case VK_HOME: 
      case VK_END: 
      case VK_BACK: 
      { 
        HWND hWnd =  GetFocus(); 
        char cn[ 32 ]; 
        GetClassName( hWnd, cn,  32  ); 
        if( strcmp( cn,  "TRxCalcEditX" ) ==  0  ){ 
          SendMessage( hWnd, pMsg->message, pMsg->wParam, pMsg->lParam ); 
          ZeroMemory( pMsg, sizeof(MSG)); 
        } 
      } 
      break; 
      }  // switch 
    break; 
    }  // switch 
  } 
  return CallNextHookEx( hh, code, wParam, lParam ); 
} 
// --------------------------------------------------------------------------- 
 
void __fastcall TActiveForm1::ActiveFormCreate(TObject *Sender) 
{ 
  RxCalcEdit = new TRxCalcEditX( this ); 
  RxCalcEdit->Parent = this; 
 
  if( hh == NULL ){ 
    hh = SetWindowsHookEx( WH_GETMESSAGE, GetMsgProc, HInstance, GetCurrentThreadId() ); 
  } 
  ++hc; 
} 
// --------------------------------------------------------------------------- 
 
void __fastcall TActiveForm1::ActiveFormDestroy(TObject *Sender) 
{ 
   --hc; 
 
  if( hc ==  0  && hh != NULL ){ 
    UnhookWindowsHookEx( hh ); 
    hh = NULL; 
  } 
 
  if( RxCalcEdit ){ 
    delete RxCalcEdit; 
    RxCalcEdit = NULL; 
  } 
} 


Ура! Стрелки в TRxCalcEditX начали работать! Но возник ряд проблем:
- Перестали работать стрелки в главном меню Internet Explorer
- Оказывается не вызывается ActiveFormDestroy, что потенциально опасно, так как хук не убирается должным образом
- По прежнему не работает кнопка Backspace, а хотелось бы

Итак неужели в C++Builder нельзя нормально реализовать аналог PreTranslateMessage() чтобы обойтись без всяких хуков?

И как заставить в ActiveX работать кнопку Backspace?
...
Рейтинг: 0 / 0
1 сообщений из 1, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / Не работают стрелки в ActiveX (C++Builder)
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]