Форум: "Начинающим";
Текущий архив: 2008.10.12;
Скачать: [xml.tar.bz2];
ВнизПомогите разобраться с простейшей программой на API Найти похожие ветки
← →
demon © (2008-08-17 17:40) [0]Вот, написал для примера исходник http://njg.890m.com/listbox.zip
Никак не могу сделать чтобы листбокс не мерцал приперерысовке.
В чем может быть дело?
← →
Правильный$Вася (2008-08-17 22:30) [1]не перерисовывать его постоянно, а только когда нужно
не перерисовывать его полностью, а только там, где нужно
← →
DVM © (2008-08-17 22:53) [2]
> demon © (17.08.08 17:40)
и еще не стирать и не рисовать фон, если ты все равно сверху нарисуешь прямоугольник.
А вообще код в WM_DRAWITEM ужасен, например вот это:
FillRect(ListDC, RectLB, CreateSolidBrush($000000) );
← →
DVM © (2008-08-17 23:13) [3]Если опустить прочие недостатки кода из [0], то вот немерцающий вариант:
program listbox_api;
uses
Windows, Messages, Types;
const
WndClass = "TWinApiWnd";
WndCaption = "Ðàáîòà ñ ListBox";
ListBoxID = 1;
var
Wc: TWndClassEx;
Wnd: HWND;
Msg: TMsg;
ListBox: THandle;
ListDC : hDC;
RectLB : TRect;
TextLB : array [0..$400] of Char;
Client:TRect;
ListLineHeight: integer;
OldLBProc: pointer;
function WindowProc( Wnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM ): LRESULT; stdcall;
begin
case Msg of
WM_DESTROY:
begin
PostQuitMessage( 0 );
Result := 0;
Exit;
end;
WM_SIZE : MoveWindow(ListBox, 10, 10, LOWORD(lparam)-20, HIWORD(lparam)-20, true);
WM_CTLCOLORLISTBOX:
begin
end;
WM_MEASUREITEM :
case wParam of
ListBoxID :
begin
with PMEASUREITEMSTRUCT(lParam)^ do
begin
itemHeight := 14;
end;
end;
end;
WM_DRAWITEM :
case wParam of
ListBoxID :
begin
RectLB := PDRAWITEMSTRUCT(lParam).rcItem;
ListDC := PDRAWITEMSTRUCT(lParam).hDC;
if (Integer(PDRAWITEMSTRUCT(lParam).ItemID) > - 1) then
begin
if ((PDRAWITEMSTRUCT(lParam).itemState and ODS_SELECTED) <> 0) then
begin // Âûäåëåíûé àéòýì
FillRect(ListDC, RectLB, CreateSolidBrush($990000) );
SetBkColor(ListDC, RGB(0,0,128) );
SetTextColor(ListDC, RGB(255,255,255) );
end
else
begin // Íå âûäåëåíûé àéòýì
FillRect(ListDC, RectLB, CreateSolidBrush($000000) );
SetBkColor(ListDC, RGB(0,0,0) );
SetTextColor(ListDC,RGB(0,255,0) );
end;
// ïåðåðûñîâûâàå&# 236; òåêñò
SendMessage(ListBox, LB_GETTEXT, PDRAWITEMSTRUCT(lParam).ItemID, LongInt(@TextLB[0]));
DrawText(ListDC, @TextLB[0], - 1, RectLB, DT_SINGLELINE or DT_VCENTER);
end;
GetClientRect(ListBox,Client);
ListLineHeight:= PDRAWITEMSTRUCT(lParam).rcItem.Bottom - PDRAWITEMSTRUCT(lParam).rcItem.top;
client.Top:= client.Top+ListLineHeight*4;
FillRect(ListDC,Client,CreateSolidBrush($000000)); // öâåò îñòàòêà ëèñòà áåç àéòýìîâ
if ((PDRAWITEMSTRUCT(lParam).itemState and ODS_FOCUS) <> 0) then DrawFocusRect(ListDC, PDRAWITEMSTRUCT(lParam).rcItem);
end;
end;
else
Result := DefWindowProc( Wnd, Msg, wParam, lParam );
end;
end;
function LBProc(Wnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
begin
case Msg of
WM_ERASEBKGND:
begin
result :=0;
end;
else
Result := CallWindowProc(OldLBProc, ListBox, Msg, wParam, lParam);
end;
end;
begin
with Wc do // ñîçäà¸ì êëàññ îêíà
begin
cbSize := SizeOf( Wc );
style := CS_HREDRAW or CS_VREDRAW;
lpfnWndProc := @WindowProc;
cbClsExtra := 0;
cbWndExtra := 0;
hInstance := hInstance;
hIcon := LoadIcon( 0, IDI_APPLICATION );
hCursor := LoadCursor( 0, IDC_ARROW );
hbrBackground := CreateSolidBrush($004499);
lpszMenuName := nil;
lpszClassName := WndClass;
end;
RegisterClassEx( Wc ); // ðåãèñòðèðóåì êëàññ îêíà
Wnd := CreateWindowEx( // Ñîçäà¸ì îêíî
0, WndClass,
WndCaption,
WS_OVERLAPPEDWINDOW or WS_CLIPCHILDREN,
400, 200, 300, 300,
0, 0, hInstance, nil );
ListBox := CreateWindowEx( // Ñîçäà¸ì ListBox
0, "Listbox", "",
WS_CHILD or WS_VISIBLE or LBS_OWNERDRAWFIXED or LBS_HASSTRINGS,
10, 10, 270, 250, Wnd,
ListBoxID, hInstance,
nil );
OldLBProc:=Pointer(SetWindowLong(ListBox, GWL_WNDPROC, longint(@LBProc)));
// ×òî-òî ñî øðèôòîì...
SendMessage( ListBox, WM_SETFONT, GetStockObject( ANSI_VAR_FONT ), 1 );
// Äîáàâëÿåì 4 ñòðîêè äëÿ ïðèìåðà
SendMessage( ListBox, LB_ADDSTRING, 0, LongInt(pchar("Ñòðî÷êà 1")));
SendMessage( ListBox, LB_ADDSTRING, 0, LongInt(pchar("Ñòðî÷êà 2")));
SendMessage( ListBox, LB_ADDSTRING, 0, LongInt(pchar("Ñòðî÷êà 3")));
SendMessage( ListBox, LB_ADDSTRING, 0, LongInt(pchar("Ñòðî÷êà 4")));
// Ïîêàçûâàåì ãëàâíîå îêíî
ShowWindow( Wnd, SW_SHOWNORMAL );
while GetMessage( Msg, 0, 0, 0 ) do
begin
TranslateMessage( Msg );
DispatchMessage( Msg );
end;
Halt( Msg.wParam );
end.
← →
demon © (2008-08-18 00:45) [4]Да, утечка хэндлов на лицо, устраню.
Спасибо, DVM, счас буду искать отличия :)
← →
Германн © (2008-08-18 00:52) [5]
> DVM © (17.08.08 23:13) [3]
>
> Если опустить прочие недостатки
Хм. Оригинальная формулировка. :)
← →
demon © (2008-08-31 23:09) [6]Этот код глючно работает, когда окно моей проги на некоторое время закрываеться, то потом листбокс не перерысовываеться.
Как исправить?
← →
DVM © (2008-08-31 23:19) [7]
> Как исправить?
объекты освобождать надо
← →
demon © (2008-09-01 00:35) [8]А поподробнее?
...я перезалил исправлений код по ссылке в первом сообщении (точнее в нулевом )
← →
Германн © (2008-09-01 01:12) [9]
> demon © (01.09.08 00:35) [8]
>
> А поподробнее?
> ...я перезалил исправлений код по ссылке в первом сообщении
> (точнее в нулевом )
>
Ну если "перезалил", то теперь "переотливай".
← →
demon © (2008-09-01 02:56) [10]Хотел промолчать...
Но как меня дастала тупость приколов некоторых пользователей! А от вас Герман я вообще пользы никакой не получил, зато ведете себя как будто админ внештатный.
Пользуясь случаем, спасибо DVM, Юрий Зотов за все.
← →
DVM © (2008-09-01 10:51) [11]
> demon © (01.09.08 00:35) [8]
>
> А поподробнее?
Посмотрел я твой код. У меня он правда работает нормально вроде, но недостатки там есть, в том числе и связанные возможно с прорисовкой неверной.
Запомни, если ты вставил в оконную процедуру окна обработку какого-либо сообщения, то ты обязан вернуть результат обработки. Для некоторых сообщений это не критично, для других чревато сбоями. Так положено. Вот, например, фрагмент твоего кода:WM_CTLCOLORLISTBOX:
begin
end;
Пустой обработчик. А в MSDN тем временем сказано, что:
Return Values
If an application processes this message, it must return the handle of a brush. Windows uses the brush to paint the background of the list box.
И это не единственное такое место в твоем коде. Раз взялся за WinAPI - будь добр играть по его правилам.
← →
demon © (2008-09-01 16:24) [12]ясно. Это осталось от экспериментов, забыл удалить.
Ладно, раз идей нету, попробую сам разобраться, может в исходнике bred2 чего отрою.
← →
DVM © (2008-09-01 16:46) [13]
> Это осталось от экспериментов, забыл удалить.
Ты сначала исправь все такие места.
← →
DVM © (2008-09-01 16:54) [14]
> может в исходнике bred2 чего отрою.
bred2 тот еще образец для подражания.
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2008.10.12;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.225 c