Форум: "WinAPI";
Текущий архив: 2005.01.30;
Скачать: [xml.tar.bz2];
ВнизМожно мне пример привести, как на окошке api текст написать? Найти похожие ветки
← →
Иван2 (2004-12-09 18:39) [0]Сколько не смотрю примеров winapi, как окошко создать - все есть, а как на нем выводить текст - нету.
← →
MBo © (2004-12-09 18:55) [1]textout drawtext
← →
Игорь Шевченко © (2004-12-09 19:10) [2]
program WinApi;
uses
Windows, Messages, SysUtils;
{$R *.RES}
function MyCoolWndProc (Window: HWND; Message, WParam: Cardinal;
LParam: Cardinal): Longint; stdcall;
var
ps : PAINTSTRUCT;
DC : HDC;
r : TRect;
begin
case Message of
WM_DESTROY:
begin
PostQuitMessage (0);
Result := 0;
Exit;
end;
WM_PAINT:
begin
dc := BeginPaint (Window, ps);
try
TextOut(DC, 0, 0, "Hello, Windows!", 15);
SetRect (R, 100, 100, 100, 100);
DrawText (DC, "Hello, world!", Length("Hello, world!"), R, DT_CALCRECT);
SetBkColor (DC, GetSysColor(COLOR_BTNFACE));
DrawText (DC, "Hello, world!", Length("Hello, world!"), R,
DT_LEFT OR DT_NOPREFIX);
OffsetRect (R, -1, -1);
Inc( R.Right, 3);
Inc( R.Bottom, 2);
DrawEdge (DC, R, EDGE_ETCHED, BF_RECT);
finally
EndPaint (Window, ps);
end;
end;
end;
Result := DefWindowProc (Window, Message, WParam, LParam);
end;
var WClass : WNDCLASS;
MyHWND : HWND;
MyMsg : MSG;
begin
WClass.hInstance := HInstance;
WClass.hIcon := 0;
WClass.hCursor := LoadCursor (0, IDC_ARROW);
WClass.hbrBackground := HBRUSH(GetStockObject(WHITE_BRUSH));
WClass.lpfnWndProc := @MyCoolWndProc;
WClass.lpszClassName := "MyCoolClass";
if RegisterClass (WClass) = 0 then begin
RaiseLastWin32Error;
Exit;
end;
MyHWND := CreateWindowEx (0, "MyCoolClass", "MyCoolWindow",
WS_OVERLAPPEDWINDOW,
Integer(CW_USEDEFAULT), Integer(CW_USEDEFAULT),
Integer(CW_USEDEFAULT), Integer(CW_USEDEFAULT),
0, 0, HInstance, nil);
if MyHWND = 0 then begin
RaiseLastWin32Error;
Exit;
end;
ShowWindow (MyHWND, SW_SHOWNORMAL);
UpdateWindow (MyHWND);
while GetMessage(MyMsg, 0, 0, 0) do begin
TranslateMessage (MyMsg);
DispatchMessage(MyMsg);
end;
end.
С уважением,
← →
Иван2 (2004-12-09 19:24) [3]Я в написании нашел, что WM_Paint нельзя посылать окну самому. А если мне надо передать ему текст и перерисовать его с новым тестом?
← →
Иван2 (2004-12-09 19:28) [4]Игорь Шевченко © :
Спасибо за пример! А если мне нужно меняющийся текст писать? А то я к Вашему коду добавил глобальную строковую константу для вывода, в программе меняю ее - а окно не меняет текст.
← →
clickmaker © (2004-12-09 19:46) [5]
> [3] Иван2 (09.12.04 19:24)
> Я в написании нашел, что WM_Paint нельзя посылать окну самому.
> А если мне надо передать ему текст и перерисовать его с
> новым тестом?
SetWindowText()
в WM_PAINT
GetWindowText(hwnd, szText);
TextOut(DC, 0, 0, szText, 15);
для принудительного освежения окна - RedrawWindow()
← →
Иван2 (2004-12-09 20:04) [6]Не понимаю. Я сделал проект,
потом на нажатии кнопки делаю создание окна как указано, только без обработки сообщений while GetMessage,
for i:=0 to 100000 do begin
ApiText:=IntToStr(i)+" %";
UpdateWindow(ApiWnd) //(с RedrawWindow не разобрался, но из хелпа выудил, что они одинаковы)
end,
а текст на нем все равно только тот, который вначале был.
← →
clickmaker © (2004-12-09 20:25) [7]
> [6] Иван2 (09.12.04 20:04)
> с RedrawWindow не разобрался
разберись
← →
GuAV © (2004-12-09 20:45) [8]Игорь Шевченко © (09.12.04 19:10) [2]
while GetMessage(MyMsg, 0, 0, 0) do
А в справке/MSDN про GetMessage написано что так нельзя..
← →
Игорь Шевченко © (2004-12-09 22:12) [9]GuAV © (09.12.04 20:45) [8]
function GetMessage(var lpMsg: TMsg; hWnd: HWND;
wMsgFilterMin, wMsgFilterMax: UINT): BOOL; stdcall;
If there is an error, the return value is -1. For example, the function fails if hWnd is an invalid window handle or lpMsg is an invalid pointer.
Я что-то делаю не так ? :)
← →
GuAV © (2004-12-09 22:29) [10]Игорь Шевченко © (09.12.04 22:12) [9]
Я что-то делаю не так ? :)
Есть такие подозрения :)
чуть ниже процитированного Вами написано:
Warning
Because the return value can be nonzero, zero, or -1, avoid code like this:
while (GetMessage( lpMsg, hWnd, 0, 0)) ...
The possibility of a -1 return value means that such code can lead to fatal application errors.
← →
GuAV © (2004-12-09 22:44) [11]Игорь Шевченко © (09.12.04 22:12) [9]
For example, the function fails if hWnd is an invalid window handle or lpMsg is an invalid pointer.
Здесь мне не нравится "For example". Наводит на мысль что возможны другие варианты :)
← →
Игорь Шевченко © (2004-12-09 23:30) [12]GuAV © (09.12.04 22:44) [11]
Тут ведь какой момент: Функция объявлена так, что возвратить что-либо кроме true или false она не может.
GetMessage возвращает -1 только в случае некорректного hWnd (в Win2k - так).
Я полагаю, что в большинстве случаев код
while GetMessage(lpMsg, 0, 0, 0) do ...
кстати, отличающийся от приведенного в MSDN, если посмотреть внимательно, вполне безопасен, и поэтому переобъявлять функцию GetMessage или сравнивать ее значение с BOOL(1) является излишним.
С уважением,
← →
GuAV © (2004-12-09 23:59) [13]Игорь Шевченко © (09.12.04 23:30) [12]
кстати, отличающийся от приведенного в MSDN,
Да, я не заментил, что в MSDN while (GetMessage( lpMsg, hWnd, 0, 0)).
Мой вариант был такой:function CheckGetMessage(Value: BOOL): BOOL;
begin
if ord(Value) = -1 then
Result := False // или RaiseLastOSError;
else
Result := Value;
end;
...
while CheckGetMessage(GetMessage(Msg, 0, 0, 0)) do
← →
Игорь Шевченко © (2004-12-10 00:15) [14]GuAV © (09.12.04 23:59) [13]
Тоже неплохо, хотя и для совсем пуристов :)
Кстати, MSDN тоже не всегда является истиной в последней инстанции.
С уважением,
← →
GuAV © (2004-12-10 00:33) [15]Игорь Шевченко © (10.12.04 0:15) [14]
Кстати, MSDN тоже не всегда является истиной в последней инстанции.
Знаю. Кое что даже я находил :) исправили :)
← →
DVM © (2004-12-10 11:42) [16]
> Игорь Шевченко © (09.12.04 19:10) [2]
> try
> TextOut(DC, 0, 0, "Hello, Windows!", 15);
..............
> DrawEdge (DC, R, EDGE_ETCHED, BF_RECT);
> finally
> EndPaint (Window, ps);
> end;
Вот уже неоднократно вижу у многих, что в try...finally...except помещаются вызовы функций API, которые не возбуждают исключений ИМХО никогда. Вопрос ЗАЧЕМ???
← →
Игорь Шевченко © (2004-12-10 11:58) [17]DVM © (10.12.04 11:42) [16]
Как это не порождают ? А Access Violation ? :))
Дурная привычка идет происходит от чтения VCL:
MemBmp := SelectObject(MaskDC, MemBmp);
try
MaskBlt(DstDC, DstX, DstY, DstW, DstH, SrcDC, SrcX, SrcY, MemBmp, MaskX,
MaskY, MakeRop4(ROP_DstCopy, SrcCopy));
finally
MemBmp := SelectObject(MaskDC, MemBmp);
DeleteObject(MemBmp);
end;
С уважением,
← →
GuAV © (2004-12-10 12:02) [18]IMHO Лучше привыкать всегда писать try..finally в таких случаях, не думая нужен или нет, чем не написать когда он нужен.
← →
Fay © (2004-12-10 13:34) [19]2 GuAV © (10.12.04 12:02) [18]
IMHO лучше всегда присать try..finally когда он нужен. Чтобы думать 8)
← →
Иван2 (2004-12-10 16:56) [20]Это все умно и красиво, но как мне добиться того, чтобы текст в окне перерисовывался после получения нового текста? Он перерисовывается только когда я перехожу между программами, и никакие UpdateWindow, RedrawWindow не помоют.
← →
DVM © (2004-12-10 17:01) [21]
> Иван2 (10.12.04 16:56) [20]
InvalidateRect()
← →
Иван2 (2004-12-10 17:15) [22]DVM © :
Спасибо! Перерисовывается! Только не понимаю, почему она какими-то полосками мерцает...
← →
DVM © (2004-12-10 17:19) [23]
> Только не понимаю, почему она какими-то полосками мерцает...
Часто обновляешь надпись? Часы небось какие-нибудь?
Чтобы не мерцало, надо сначала рисовать в память, а затем на DC окна с пом BitBlt() копировать из памяти изображение.
← →
Иван2 (2004-12-10 17:30) [24]DVM © :
Ну, часто. В смысле, в приведенном мной тесте часто. То есть на получении сообщения с новым текстом рисовать в память, а на WM_Paint копировать из памяти? А чем рисовать в память?
← →
DVM © (2004-12-10 17:38) [25]
> А чем рисовать в память?
Тем же чем и на окно. Надо создать контекст устройства в памяти, совместимый с контекстом окна (CreateCompatibleDC). Далее создать битмап подходящих размеров (CreateCompatibleBitmap) и выбрать его в контекст в памяти (SelectObject). Потом рисуем на этот контест все что захотим и потом с него копируем на контекст окна (BitBlt). Не забываем уничтожать созданные объекты и освобождать DC.
Кстати в твоем случае лучше поступить так:
Стереть старое изображение заполнив его прямоугольник нужным цветом (FillRect), а потом отрисовать непосредственно новую картинку. Это не в WM_PAINT, а просто в отдельной процедуре, которую вызвать там когда надо.
← →
Иван2 (2004-12-10 17:41) [26]Понял, спасибо большое!
Страницы: 1 вся ветка
Форум: "WinAPI";
Текущий архив: 2005.01.30;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.034 c