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

Вниз

Помогите разобраться с простейшей программой на 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   // &#194;&#251;&#228;&#229;&#235;&#229;&#237;&#251;&#233; &#224;&#233;&#242;&#253;&#236;
                   FillRect(ListDC, RectLB, CreateSolidBrush($990000) );
                   SetBkColor(ListDC, RGB(0,0,128) );
                   SetTextColor(ListDC, RGB(255,255,255) );
                 end
               else
                 begin   // &#205;&#229; &#226;&#251;&#228;&#229;&#235;&#229;&#237;&#251;&#233; &#224;&#233;&#242;&#253;&#236;
                   FillRect(ListDC, RectLB, CreateSolidBrush($000000) );
                   SetBkColor(ListDC,  RGB(0,0,0) );
                   SetTextColor(ListDC,RGB(0,255,0) );
                 end;
               // &#239;&#229;&#240;&#229;&#240;&#251;&#241;&#238;&#226;&#251;&#226;&#224;&#229;&# 236; &#242;&#229;&#234;&#241;&#242;
               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));     // &#246;&#226;&#229;&#242; &#238;&#241;&#242;&#224;&#242;&#234;&#224; &#235;&#232;&#241;&#242;&#224; &#225;&#229;&#231; &#224;&#233;&#242;&#253;&#236;&#238;&#226;

           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     // &#241;&#238;&#231;&#228;&#224;&#184;&#236; &#234;&#235;&#224;&#241;&#241; &#238;&#234;&#237;&#224;
  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 );    // &#240;&#229;&#227;&#232;&#241;&#242;&#240;&#232;&#240;&#243;&#229;&#236; &#234;&#235;&#224;&#241;&#241; &#238;&#234;&#237;&#224;

  Wnd := CreateWindowEx(    // &#209;&#238;&#231;&#228;&#224;&#184;&#236; &#238;&#234;&#237;&#238;
  0, WndClass,
  WndCaption,
  WS_OVERLAPPEDWINDOW or WS_CLIPCHILDREN,
  400, 200, 300, 300,
  0, 0, hInstance, nil );

  ListBox := CreateWindowEx(   // &#209;&#238;&#231;&#228;&#224;&#184;&#236; 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)));

  // &#215;&#242;&#238;-&#242;&#238; &#241;&#238; &#248;&#240;&#232;&#244;&#242;&#238;&#236;...
  SendMessage( ListBox, WM_SETFONT, GetStockObject( ANSI_VAR_FONT ), 1 );

  // &#196;&#238;&#225;&#224;&#226;&#235;&#255;&#229;&#236; 4 &#241;&#242;&#240;&#238;&#234;&#232; &#228;&#235;&#255; &#239;&#240;&#232;&#236;&#229;&#240;&#224;
  SendMessage( ListBox, LB_ADDSTRING, 0, LongInt(pchar("&#209;&#242;&#240;&#238;&#247;&#234;&#224; 1")));
  SendMessage( ListBox, LB_ADDSTRING, 0, LongInt(pchar("&#209;&#242;&#240;&#238;&#247;&#234;&#224; 2")));
  SendMessage( ListBox, LB_ADDSTRING, 0, LongInt(pchar("&#209;&#242;&#240;&#238;&#247;&#234;&#224; 3")));
  SendMessage( ListBox, LB_ADDSTRING, 0, LongInt(pchar("&#209;&#242;&#240;&#238;&#247;&#234;&#224; 4")));

  // &#207;&#238;&#234;&#224;&#231;&#251;&#226;&#224;&#229;&#236; &#227;&#235;&#224;&#226;&#237;&#238;&#229; &#238;&#234;&#237;&#238;
  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;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.016 c
13-1121805388
NewWonder
2005-07-20 00:36
2008.10.12
C#: Borland or MS?


15-1219221012
Petr V. Abramov
2008-08-20 12:30
2008.10.12
Wifi


2-1220256443
Q123
2008-09-01 12:07
2008.10.12
Универсальный метод для сортировки масивов.


3-1207245676
kotyara12
2008-04-03 22:01
2008.10.12
Рекурсивная выборка из таблицы со структурой дерева


15-1219071733
Renegat
2008-08-18 19:02
2008.10.12
Помогите с идентификацией музыки