Форум: "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