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

Вниз

Изменение оконной функции Callback...   Найти похожие ветки 

 
Wolfheart   (2006-06-23 16:21) [0]

Доброго времени суток.
Хотелось бы обратиться за помощью к колегам-программистам...
Ситуация следующая. Имеется программа, написанная на "чистом" WinAPI: окно, два компонента (Button, GroupBox). Кнопке назначается реакция на событие WM_CLICK - при щелчке выводится некое сообщение. Если заставить GroupBox "усыновить" Кнопку, т.е. сменить ParentHandle, то всякая реакция кнопки на щелчек отсутствует - она запросто игнорирует все попытки добиться вывода желаемого сообщения.
Насколько я смог разобраться, для того, чтобы перехватить сообщения у окна (кнопки), родителем которого не является MainWindow, требуется с помощью функции SetWindowLong установить соотвествующий Pointer на CallBack-функцию... Увы, у меня ничего не вышло - всяческие хитроумные манипуляции приводят к исчезновению злополучной кнопки и на этом всё заканчивается...
Пожалуйста, помогите разобраться с этой проблемой!
Заранее благодарен.


 
Сергей М. ©   (2006-06-23 16:26) [1]

Цитата из справки:

Remarks

The SetWindowLong function fails if the window specified by the hWnd parameter does not belong to the same process as the calling thread.

Это условие тобой соблюдено ?


 
Rouse_ ©   (2006-06-23 16:35) [2]

Смотри пример, здесь RadioButton лежат на двух GroupBox:

////////////////////////////////////////////////////////////////////////////////
//
//  ****************************************************************************
//  * Unit Name : dlgEstimate
//  * Purpose   : Диалог настройки параметров фильтра
//  * Author    : Александр Багель
//  * Copyright : Центр Гранд 2001 - 2004 г.
//  * Version   : 1.01
//  ****************************************************************************
//
unit dlgEstimate;

interface

uses
 Windows, Messages, ARPSConsts;

resourcestring
 TXT_CAPTION = "Фильтр импорта файлов формата ARPS";
 TXT_CANCEL = "Отмена";
 TXT_OK = "Применить";
 TXT_PRICE = "Тип расценок";
 TXT_DIGEST = "Тип сборников";
 TXT_TER = "ТЕР";
 TXT_FER = "ФЕР";
 TXT_GSN = "ГЭСН";
 TXT_STR = "Строительные";
 TXT_MNT = "Монтажные";
 TXT_PSK = "Пусконаладочные";

type
 TWindowProc = function(Wnd: HWND; Msg: Integer;
 WParam: WPARAM; LParam: LPARAM): LRESULT; stdcall;

var
 MainWindow    : TWndClassEx;
 Handle,
 hFontNormal,
 btnOk,
 btnCancel,
 gbPrice,
 gbDigest,
 rbTer,
 rbFer,
 rbGasn,
 rbStroy,
 rbMont,
 rbPusk        : HWND;
 Msg           : TMsg;
 Left,
 Top,
 Width,
 Height        : Integer;
 StatusDone    : Boolean;
 Request       : TRequest;
 Start         : Boolean;
 WPA, WPB      : Integer;

 function ShowEctimateDlg: TRequest;

implementation

// Смотрим - че за хрень у нас выбрана
// =============================================================================
procedure GetRequest;
var
 Checked: Integer;
begin
 Request.Price := apTer;
 Checked := SendMessage(rbTer, BM_GETCHECK, 0, 0);
 if Checked <> BST_CHECKED then
 begin
   Request.Price := apFer;
   Checked := SendMessage(rbFer, BM_GETCHECK, 0, 0);
   if Checked <> BST_CHECKED then
     Request.Price := apGasn;
 end;
 Request.Digest := adS;
 Checked := SendMessage(rbStroy, BM_GETCHECK, 0, 0);
 if Checked <> BST_CHECKED then
 begin
   Request.Digest := adM;
   Checked := SendMessage(rbMont, BM_GETCHECK, 0, 0);
   if Checked <> BST_CHECKED then
     Request.Digest := adP;
 end;
end;

// Центрирование формы
// =============================================================================
procedure CenterMainForm;
var
 ScrWidth, ScrHeight: Cardinal;
begin
 ScrWidth := GetSystemMetrics(SM_CXSCREEN);
 ScrHeight := GetSystemMetrics(SM_CYSCREEN);
 Left := (Integer(ScrWidth) - Width) div 2;
 Top := (Integer(ScrHeight) - Height) div 2;
end;

// Главная оконная процедура
// =============================================================================
function WindowProc(Wnd: HWND; Msg: Integer;
 WParam: WPARAM; LParam: LPARAM): LRESULT; stdcall;
begin
 case Msg of
   WM_DESTROY:
     Start := False;
   WM_COMMAND:
   begin
     case LoWord(WParam) of
       100:
       begin
         GetRequest;
         Start := False;
       end;
       105:
         Start := False;
     end;
   end;
   WM_CHAR:
   begin
     case WParam of
       13: PostMessage(Handle, WM_COMMAND, MakeWord(100, BN_CLICKED), 0);
       27: PostMessage(Handle, WM_COMMAND, MakeWord(105, BN_CLICKED), 0);
     end;
   end;
 end;
 Result := DefWindowProc(Wnd, Msg, WParam, LParam);
end;

// Оконная процедура для первого GroupBox-a
// =============================================================================
function WindowProcA(Wnd: HWND; Msg: Integer;
 WParam: WPARAM; LParam: LPARAM): LRESULT; stdcall;
begin
 CallWindowProc(Pointer(WPA), Wnd, Msg, WParam, LParam);
 Result := DefWindowProc(Wnd, Msg, WParam, LParam);
end;

// Оконная процедура для второго GroupBox-a
// =============================================================================
function WindowProcB(Wnd: HWND; Msg: Integer;
 WParam: WPARAM; LParam: LPARAM): LRESULT; stdcall;
begin
 CallWindowProc(Pointer(WPB), Wnd, Msg, WParam, LParam);
 Result := DefWindowProc(Wnd, Msg, WParam, LParam);
end;


 
Rouse_ ©   (2006-06-23 16:35) [3]

// Показ диалога
// =============================================================================
function ShowEctimateDlg: TRequest;
begin
 with MainWindow do
 begin
   cbSize := SizeOf(MainWindow);
   style := CS_HREDRAW or CS_VREDRAW;
   lpfnWndProc := @WindowProc;
   cbClsExtra := 0;
   cbWndExtra := 0;
   hIcon := LoadIcon(0, IDI_APPLICATION);
   hCursor  := LoadCursor(0, IDC_ARROW);
   hbrBackground := COLOR_BTNFACE + 1;
   lpszMenuName := nil;
   lpszClassName := "TARPSEstimateDialog";
 end;
 MainWindow.hInstance := HInstance;
 Request.Price := apErr;
 Request.Digest := adErr;  
 if RegisterClassEx(MainWindow) = 0 then Exit;
 try
   Width := 370;
   Height := 187;
   CenterMainForm;

   Handle := CreateWindowEx(0, "TARPSEstimateDialog",
     PChar(APP_TITLE), WS_OVERLAPPED or WS_SYSMENU,
     Left, Top, Width, Height, APP_INST, 0, HInstance, nil);

   SendMessage(Handle, WM_SETICON, 1, LoadIcon(HInstance, "MAINICON"));

   btnOk := CreateWindowEx(0, "BUTTON", PChar(TXT_OK),
     BS_PUSHBUTTON or WS_CHILD or WS_VISIBLE or BS_DEFPUSHBUTTON,
     276, 120, 75, 25, Handle, 100, hInstance, nil);

   btnCancel := CreateWindowEx(0, "BUTTON", PChar(TXT_CANCEL),
     BS_PUSHBUTTON or WS_CHILD or WS_VISIBLE,
     196, 120, 75, 25, Handle, 105, hInstance, nil);

   gbPrice := CreateWindowEx(0, "BUTTON", PChar(TXT_PRICE),
     BS_GROUPBOX or WS_CHILD or WS_VISIBLE,
     8, 8, 169, 105, Handle, 0, hInstance, nil);

   gbDigest := CreateWindowEx(0, "BUTTON", PChar(TXT_DIGEST),
     BS_GROUPBOX or WS_CHILD or WS_VISIBLE,
     184, 8, 169, 105, Handle, 0, hInstance, nil);

   rbTer := CreateWindowEx(0, "BUTTON", PChar(TXT_TER),
     BS_AUTORADIOBUTTON or WS_CHILD or WS_VISIBLE,
     16, 24, 113, 17, gbPrice, 1, hInstance, nil);

   rbFer := CreateWindowEx(0, "BUTTON", PChar(TXT_FER),
     BS_AUTORADIOBUTTON or WS_CHILD or WS_VISIBLE,
     16, 48, 113, 17, gbPrice, 2, hInstance, nil);

   rbGasn := CreateWindowEx(0, "BUTTON", PChar(TXT_GSN),
     BS_AUTORADIOBUTTON or WS_CHILD or WS_VISIBLE,
     16, 72, 113, 17, gbPrice, 3, hInstance, nil);

   rbStroy := CreateWindowEx(0, "BUTTON", PChar(TXT_STR),
     BS_AUTORADIOBUTTON or WS_CHILD or WS_VISIBLE,
     16, 24, 113, 17, gbDigest, 4, hInstance, nil);

   rbMont := CreateWindowEx(0, "BUTTON", PChar(TXT_MNT),
     BS_AUTORADIOBUTTON or WS_CHILD or WS_VISIBLE,
     16, 48, 113, 17, gbDigest, 5, hInstance, nil);

   rbPusk := CreateWindowEx(0, "BUTTON", PChar(TXT_PSK),
     BS_AUTORADIOBUTTON or WS_CHILD or WS_VISIBLE,
     16, 72, 113, 17, gbDigest, 6, hInstance, nil);

   SendMessage(rbTer, BM_SETCHECK, 1, 0);
   SendMessage(rbStroy, BM_SETCHECK, 1, 0);

   hFontNormal := CreateFont(-11, 0, 0, 0, FW_NORMAL, 0, 0, 0, DEFAULT_CHARSET,
                       OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
                       DEFAULT_PITCH or FF_DONTCARE, "MS Sans Serif");  

   if hFontNormal <> 0 then
   begin
     SendMessage(btnOk, WM_SETFONT, hFontNormal, 0);
     SendMessage(btnCancel, WM_SETFONT, hFontNormal, 0);
     SendMessage(gbPrice, WM_SETFONT, hFontNormal, 0);
     SendMessage(gbDigest, WM_SETFONT, hFontNormal, 0);
     SendMessage(rbTer, WM_SETFONT, hFontNormal, 0);
     SendMessage(rbFer, WM_SETFONT, hFontNormal, 0);
     SendMessage(rbGasn, WM_SETFONT, hFontNormal, 0);
     SendMessage(rbStroy, WM_SETFONT, hFontNormal, 0);
     SendMessage(rbMont, WM_SETFONT, hFontNormal, 0);
     SendMessage(rbPusk, WM_SETFONT, hFontNormal, 0);
   end;    

   WPA := GetWindowLong(gbPrice, GWL_WNDPROC);
   SetWindowLong(gbPrice, GWL_WNDPROC, Integer(@WindowProcA));
   WPB := GetWindowLong(gbDigest, GWL_WNDPROC);
   SetWindowLong(gbDigest, GWL_WNDPROC, Integer(@WindowProcB));

   ShowWindow(Handle, SW_SHOW);
   SetWindowPos(Handle, HWND_TOP, 0, 0, 0, 0,
     SWP_NOSIZE or SWP_NOMOVE);

   Start := True;

   while GetMessage(Msg, 0, 0, 0) and Start do
   begin
     TranslateMessage(Msg);
     DispatchMessage(Msg);
   end;

   DestroyWindow(Handle);
 finally
   UnregisterClass("TARPSEstimateDialog", HInstance);
 end;
 Result := Request;
end;

end.


 
Wolfheart   (2006-06-23 16:49) [4]

Сергей М.,
Да, данное условие мною соблюдено...

Rouse_,
Искренне признателен за оказанную Вами помощь!


 
Rouse_ ©   (2006-06-23 19:44) [5]


> Искренне признателен за оказанную Вами помощь!

Незачто, и пардон за коментарий первой продцедуры - исходник рабочий, недоглядел :)


 
Игорь Шевченко ©   (2006-06-23 20:00) [6]


> Если заставить GroupBox "усыновить" Кнопку, т.е. сменить
> ParentHandle, то всякая реакция кнопки на щелчек отсутствует
> - она запросто игнорирует все попытки добиться вывода желаемого
> сообщения


все правильно. сообщения о событиях дочерних элементов управления, в том числе и кнопки приходят в оконную процедуру родительского окна. На мой взгляд, требуется дописать оконную процедуру GroupBox"а обработкой сообщений WM_COMMAND



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

Форум: "WinAPI";
Текущий архив: 2006.11.12;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.48 MB
Время: 0.044 c
15-1161670447
zdm
2006-10-24 10:14
2006.11.12
mdi


1-1159538518
_Guest_
2006-09-29 18:01
2006.11.12
загрузка dll-ки


15-1161513590
SerJaNT
2006-10-22 14:39
2006.11.12
ShellListView


15-1161875174
oldman
2006-10-26 19:06
2006.11.12
Магия чисел?


15-1147981014
Eraser
2006-05-18 23:36
2006.11.12
Remote Office Manager - бета тестирование





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский