function windowproc(wnd:hwnd; msg,wparam,lparam:LongInt):LongInt; stdcall;Вот простая оконная процедура, которая реагирует на выход. Зачем нужно
begin
case msg of
WM_DESTROY: begin
PostQuitMessage(0);
Result:=0;
exit;
end;
end;
Result:=DefWindowProc(wnd,msg,wparam,lparam)
end;
Result:=0;и сразу после этого EXIT и после case
Result:=DefWindowProc(wnd,msg,wparam,lparam)?
Ты ловишь нужное тебе сообщение, и обрабатываешь его. После этого надо выйти из обработчика, так? Вот и возвращается 0, чтобы показать, что сообщение уже обработано. А если поступило сообщение, которое ты НЕ предусмотрел (или не хочешь обрабатывать), то вызывается DefWindowProc - дефолтный обработчик сообщений окна. Именно в нем стандартно обрабатываются все изменения размеров окна, минимизация/максимизация, перетаскивание окна по десктопу, и т.д... Если будешь обрабатывать ВСЕ без исключения сообщения Windows, связанные с твоим окном - с ума сойдешь, их сотни, если не тысячи
Result:=DefWindowProc(wnd,msg,wparam,lparam)Без нее даже не запустилась программа
hIcon:=loadicon (0, IDI_APPLICATION);А как загрузить другой курсор и иконку?
hCursor:=loadcursor(0, IDC_ARROW);
101 ICON "Icon.ico"
constТо же самое - с курсором...
IDI_MyOwnIcon = 101; // <--- должно совпадать с ID в файле ресурсов
...
hIcon := LoadIcon(GetModuleHandle(nil), MAKEINTRESOURCE(IDI_MyOwnIcon));
а как добавить этот файл? PROJECT- add... ?
Если он у тебя уже есть, то добавить можно через Project->Add. Если нет - то создай (через Windows Explorer) пустой файл в папке с проектом (с расширением RC), и добавляй его...
создал файл и через блокнот в него добавил
101 ICON "Icon.ico"Призапуске ругается на эту строчку
А файл с иконкой (тот самый Icon.ico) где? Ты же хочешь свою иконку, а не стандартную, значит, она должна у тебя быть.
Списибо!
курсор получился)
Вот я создал меню с пунктами и при нажатии на них выскакивает сообщение. А как при выборе пункта меню осуществить нажатие другого пункта? или вообще кнопки (что-то вроде Button2.click(sender))
У SendMessage же 4 параметра - hwnd, msg, и 2 параметра. Как тут быть?
SendMessage(hWnd, WM_COMMAND, btnID, 0);
SendMessage(btn,?,0,0);и команду не знал.
по поводу сабклассинга я не понял как работают функции SetWindowLong, CallWindowProc, GetWindowLong.
Что непонятно с этими функциями? Ну, устанавливает она атрибут окна, это все, что тебе надо о ней знать. Как работает CreateWindow или GetDC тебе понятно? Оно тебе не надо на данном этапе.
Вот описание второй функции по-русски: http://www.firststeps.ru/mfc/winapi/win/r.php?94, а CallWindowProc просто вызывает оконную функцию, передаваемую ей в первом параметре. Зачем это нужно? Ну, допустим, ты написал свою процедуру обработки тех сообщений, которые тебе нужны, обработал их. А что дальше? Те, которые НЕ обрабатываются твоей процедурой, что, будут потеряны? Нет, ты просто берешь адрес старой (настоящей, неподмененной) оконной процедуры того окна, которое сабклассируешь, и вызываешь ее.
Помнишь, что произошло, когда ты не вызвал DefWindowProc для своего окна? Вот примерно то же самое будет, если не вызвать старую процедуру сабклассированного окна. Ты-то перехватил все, что тебе надо было, а мало ли что окно еще обрабатывает... Вот и пусть обрабатывает само, тебе-то это зачем?
Подобная техника применяется при написании обработчиков прерываний (никогда не делал? ) - пишешь свой обработчик, скажем, таймера, выполняешь что-то свое, а потом вызываешь прежний, системный обработчик...
{ Модифицированная оконная процедура поля ввода }
function EditWinProc(hWnd: HWND; uMsg: UINT;
wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
begin
case uMsg of
{ Запрещаем показ контекстного меню }
WM_CONTEXTMENU:
begin
Result := 0;
MessageBeep(0);
Exit; // тут выходим из всей процедуры или из case?
end;
end;
{ Не забываем вызвать оригинальную оконную процедуру }
Result := CallWindowProc(Pointer(GetWindowLong(hWnd, GWL_USERDATA)),
hWnd, uMsg, wParam, lParam);
end;
{Модифицированная оконная процедура кнопки }В 1 функции - если произошло нужное событие, то выполняем что надо и EXit- выход из функции. А во 2 функции, если в оригинальной оконной процедуре есть обработчик WM_LBUTTONDOWN то выполнится работа с таймером а потом и другое? Тут EXIT'а нету
function BtnWinProc(hWnd: HWND; uMsg: UINT;
wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
begin
case uMsg of
{ При нажатии мыши запускаем таймер, интервал - 10 миллисекунд }
WM_LBUTTONDOWN: SetTimer(hWnd, BtnTimer, 10, @BtnTimerProc);
{ При отпускании мыши уничтожаем таймер }
WM_LBUTTONUP:
begin
KillTimer(hWnd, BtnTimer);
{ Восстанавливаем прежний текст }
SetWindowText(hWnd, BtnText);
end;
end;
{ Не забываем вызвать оригинальную оконную процедуру }
Result := CallWindowProc(Pointer(GetWindowLong(hWnd, GWL_USERDATA)),
hWnd, uMsg, wParam, lParam);
end;
Спасибо,понял. Теперь можно и спать идти
Привет
По поводу суперклассинга - берем уже имеющийся класс, меняем его, указав новую процедуру, регистрируем класс и создаем окна нового класса. При выходе удаляем класс. Правильно понял?
Правильно... Осталось теперь реализовать
я пока по примеру с вингарда
А на изменение размера формы какое сообщение поступает? на WM_RESIZE ругается. Возможно wm_size?
Это смотря когда... Во время изменения размера постоянно приходит WM_SIZING; сразу после того, как пользователь отпустил мышу (размер установлен окончательно) - приходит WM_SIZE.
Спасиб, показываю координаты окна при передвижении и ресайзе
Вот попробовал добавить кнопку в другое окно, и хоть для меня странно, но получилось И какие еще чтучки можно сделать?
А можно создать кнопку скругленной или вообще другой формы?
И почему после выхода из моей программы кнопка удаляется?
Эскизы прикрепленных изображений
А если ты класс создал, значит должен удалить:
При создании класса
hInstance := hInstance;Хотя у меня нету переменной hInstance. В коде когда навожу мышу показыват что вроде как системная константа
Спасибо за ответы.
Еще пара вопросов и все
Суперклассинг. В примере на вингарде создавали едиты и они удалялись при нажатии на них. Тут модернизировали класс едита. А если уже есть эти же самые едиты и на них надо поставить обработчик на нажатие клавиши, то тут как быть? не переделывать класс?
И сабклассинг другого приложения. Есть пример для новичка? Засабклассировать кнопку или едит, а там пример, половина написана на ассемблере. Для меня "без шансов"
Т.е. надо сабклассировать каждый едит?
Для каждого EDIT-а, для которого надо поймать нажатия, придется подменить оконную функцию. Ты это хотел услышать?
Да. Списибо!
#include "stdafx.h"Как будет выглядеть на дельфи эта часть кода
#include "iostream.h"
#include "afxwin.h"
void main()
{
HWND hwnd;
hwnd = GetDesktopWindow();
HDC hdc;
hdc=GetWindowDC(hwnd);
int i;
cin >> i;
CPen pen(PS_SOLID,4,RGB(255,0,0));
SelectObject(hdc,pen);
Ellipse(hdc,-100,-100,100,100);
}
int i; // описание типа integer
cin >> i; //типа read (i) ?
CPen pen(PS_SOLID,4,RGB(255,0,0));
Ну поскольку введенное i нигде не используется, то и на фиг оно не надо... А все остальное - вот так, например:
varправда, много изменений? Только вот мой кусок - рабочий, а твой - вряд ли...
myDC: HDC;
ps: PAINTSTRUCT;
myPen: HPEN;
...
case AMessage of
WM_PAINT:
begin
myDC := BeginPaint(Window, ps);
myPen := CreatePen(PS_SOLID, 4, RGB(255, 0, 0));
SelectObject(myDC, myPen);
Ellipse(myDC, -100, -100, 100, 100);
EndPaint(Window, ps);
Exit(0);
end;
...