Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.11.12;
Скачать: CL | DM;

Вниз

Изменение оконной функции 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 вся ветка

Текущий архив: 2006.11.12;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.042 c
15-1161323524
xayam
2006-10-20 09:52
2006.11.12
Уравнение любви


6-1151325615
Cker
2006-06-26 16:40
2006.11.12
Get-запрос


2-1161870569
RebroFF
2006-10-26 17:49
2006.11.12
TSQL


15-1161626515
Layner
2006-10-23 22:01
2006.11.12
А кто знает, как троллейбусы перекл. с ветки на ветку?


15-1161749235
Palladin
2006-10-25 08:07
2006.11.12
Марка самолета