Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 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   // &#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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.225 c
2-1220447536
tropik
2008-09-03 17:12
2008.10.12
Как заинсталить компонент в Delphi 2 ?


2-1220452724
FIL-23
2008-09-03 18:38
2008.10.12
Двойное нажатие мышкой...


15-1219471047
Simpson
2008-08-23 09:57
2008.10.12
Указатель класса на самого себя


15-1219142604
tytus
2008-08-19 14:43
2008.10.12
Не удаляется выделенный блок в редакторе...


15-1219388772
rx275d7_jedi
2008-08-22 11:06
2008.10.12
Delphi 7 or Delphi 2005





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский