Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2004.08.22;
Скачать: [xml.tar.bz2];

Вниз

Определение, по какой колонке сделан щелчок в ListView   Найти похожие ветки 

 
AD_infiniTUM   (2004-07-12 18:25) [0]

Как определить, по какой колонке сделан щелчок в ListView? Если я правильно понял, то нужно перехватывать сообщение WM_NOTIFY. А как дальше?
Заранее спасибо.


 
NAlexey ©   (2004-07-13 09:40) [1]


procedure ListViewWndProc(var Message: TMessage);
 case Message.Msg of
   WM_NOTIFY:
   case HD_NOTIFY(Pointer(Message.LParam)^).Hdr.code of
     HDN_ITEMCLICK:
     begin
       if HD_NOTIFY(Pointer(Message.LParam)^).Item = 0 then
         . . .
     end;
   end;


 
AD_infiniTUM   (2004-07-13 10:49) [2]

Почему-то срабатывает только при щелчке по заголовку первой колонки, а как со стальными колонками? Может я что-то не так делаю...
Вот код:
function ListViewWndProc(Wnd: HWnd; Msg: Cardinal; wParam,
 lParam: Cardinal): Cardinal; stdcall;
begin
 Result := CallWindowProc(Pointer(ListviewProc), Wnd, Msg, wParam, lParam);
 case Msg of
   WM_NOTIFY:
     case HD_NOTIFY(Pointer(LParam)^).Hdr.code of
       HDN_ITEMCLICK: if HD_NOTIFY(Pointer(LParam)^).Item = 0 then
         MessageBox(0, "Сделан щелчок по колонке", "Message");
     end;
 end;
end;


 
NAlexey ©   (2004-07-13 10:52) [3]

>AD_infiniTUM   (13.07.04 10:49) [2]
Ты чего?


 
NAlexey ©   (2004-07-13 11:11) [4]

Ааааа, извиняюсь. Это я чего. Пробуй так:

procedure TForm1.FormCreate(Sender: TObject);
begin
 FOldWndProc := ListView1.WindowProc;
 ListView1.WindowProc := NewWndProc;
end;

procedure TForm1.NewWndProc(var Message: TMessage);
begin
 case Message.Msg of
   WM_NOTIFY:
   case HD_NOTIFY(Pointer(Message.LParam)^).Hdr.code of
     HDN_ITEMCLICKW:
       ShowMessage(IntToStr(HD_NOTIFY(Pointer(Message.LParam)^).Item));
   end;
 end;
 if Assigned(FOldWndProc) then
   FOldWndProc(Message);
end;


 
AD_infiniTUM   (2004-07-13 11:23) [5]

Теперь на первом столбце тоже перестало работать. Т.е. вообще не работает.


 
NAlexey ©   (2004-07-13 11:24) [6]

>AD_infiniTUM   (13.07.04 11:23) [5]
Ты полностью скопировал мой пример или сам правил? Убедись что ты используешь HDN_ITEMCLICKW а не HDN_ITEMCLICK. У меня пример работает.


 
AD_infiniTUM   (2004-07-13 11:30) [7]

Нет не полностью. У меня программа на WinApi, поэтому я преобразовал код соответствующим образом.
procedure TForm1.FormCreate(Sender: TObject);
begin
FOldWndProc := ListView1.WindowProc;
ListView1.WindowProc := NewWndProc;
end;

на
ListViewProc := SetWindowLong(ListView,
   GWL_WNDPROC, Integer(@ListViewWndProc));

а
Второк кусок на

function ListViewWndProc(Wnd: HWnd; Msg: Cardinal; wParam, lParam: Cardinal): Cardinal; stdcall;
begin
 Result := CallWindowProc(Pointer(ListViewProc), Wnd, Msg, wParam, lParam);

 case Msg of
   WM_NOTIFY:
     case HD_NOTIFY(Pointer(LParam)^).Hdr.code of
       HDN_ITEMCLICKW:
         MsgBox(0, Int2Str(HD_NOTIFY(Pointer(LParam)^).Item), "");
     end;
 end;
end;



 
NAlexey ©   (2004-07-13 11:34) [8]

Вот так:

function ListViewWndProc(Wnd: HWnd; Msg: Cardinal; wParam, lParam: Cardinal): Cardinal; stdcall;
begin
case Msg of
  WM_NOTIFY:
    case HD_NOTIFY(Pointer(LParam)^).Hdr.code of
      HDN_ITEMCLICKW:
        MsgBox(0, Int2Str(HD_NOTIFY(Pointer(LParam)^).Item), "");
    end;
end;
Result := CallWindowProc(Pointer(ListViewProc), Wnd, Msg, wParam, lParam);
end;


 
AD_infiniTUM   (2004-07-13 11:40) [9]

NAlexey
Спасибо, заработало. Вообще я почему-то домал, что в данном случае положение CallWindowProc (в самом низу или в самом верху функции) не влияет на работоспособность...


 
NAlexey ©   (2004-07-13 11:43) [10]

>AD_infiniTUM   (13.07.04 11:40) [9]
Посмотри исходники TListView и поймешь в чем дело.


 
AD_infiniTUM   (2004-07-13 13:17) [11]

И еще можно вопрос по ListView?
Отсортировать элементы можно функцией
function ListView_SortItems(hwndLV: HWND; pfnCompare: TLVCompare; lPrm: Longint): Bool;

TLVCompare это
function(lParam1, lParam2, lParamSort: Integer): Integer stdcall;

Как осортировать элементы? Что передается в lParam1(2)? В TListView это TListItem?


 
NAlexey ©   (2004-07-13 13:41) [12]

>Как осортировать элементы? Что передается в lParam1(2)? В TListView это TListItem?
Сортируй и объявляй также как делаешь обычно в TListView:

function MySortFunc(lParam1, lParam2: TListView; lParamSort: Integer): Integer stdcall;

вызывай:

ListView_SortItems(Handle, @MySortFunc, 0);

А там уже сравнивай как тебе надо.


 
AD_infiniTUM   (2004-07-13 14:11) [13]

function MySortFunc(lParam1, lParam2: TListView; lParamSort: Integer): Integer stdcall;

Тут вместо TListView, видимо, TListItem.


> Сортируй и объявляй также как делаешь обычно в TListView:

Так у меня нет TListView. Если его подключать, то с ним же Forms. Все преимущества в размере программы пропадутут.

Попробовал
function MySortFunc(lParam1, lParam2, lParamSort: Integer): Integer stdcall;
В lParam1, lParam2 всегда почему-то передаются нули...


 
NAlexey ©   (2004-07-13 14:18) [14]


function MySortFunc(lParam1, lParam2: TListItem;
 lParamSort: Integer): Integer stdcall;
begin
 Result := AnsiCompareStr(lParam1.Caption, lParam2.Caption);
end;

procedure TForm1.ListView1ColumnClick(Sender: TObject;
 Column: TListColumn);
begin
 ListView_SortItems(LIstView1.Handle, @MySortFunc, 0);
end;


 
AD_infiniTUM   (2004-07-13 14:23) [15]

NAlexey
Спасибо за старания.
Но у меня нет TListItem. Программа работает без VCL... Чем заменить в этой функции TListItem, если программа только на WinApi?


 
NAlexey ©   (2004-07-13 14:42) [16]

Блин, опять забыл. Тогда так:

function MySortFunc(lParam1, lParam2, lParamSort: Integer): Integer stdcall;
var
 FindInfo: tagLVFINDINFO;
 iIndex1, iIndex2: Integer;
 buf1: array[0..MAX_PATH] of Char;
 buf2: array[0..MAX_PATH] of Char;
begin
 FindInfo.flags := LVFI_PARAM;
 FindInfo.lParam := lParam1;
 iIndex1 := ListView_FindItem(Form1.ListView1.Handle, -1, FindInfo);
 FindInfo.lParam := lParam2;
 iIndex2 := ListView_FindItem(Form1.ListView1.Handle, -1, FindInfo);
 ListView_GetItemText(Form1.ListView1.Handle, iIndex1, 0, buf1, SizeOf(buf1));
 ListView_GetItemText(Form1.ListView1.Handle, iIndex2, 0, buf1, SizeOf(buf2));
 Result := AnsiCompareStr(buf1, buf2);
end;

procedure TForm1.ListView1ColumnClick(Sender: TObject;
 Column: TListColumn);
begin
 ListView_SortItems(LIstView1.Handle, @MySortFunc, 0);
end;


 
AD_infiniTUM   (2004-07-13 15:07) [17]

NAlexey
Еще одна проблема, как я писал выше, в функцию сортировки lParam1, lParam2 передаются всегда равные 0, все время сравнивается с собой один элемент, в итоге ничего не сортируется.

Может при добавлении Item"ов в LVItem.lparam нужно что-нибудь заносить?


 
NAlexey ©   (2004-07-13 15:12) [18]

>AD_infiniTUM   (13.07.04 15:07) [17]
А как ты добавляешь?


 
AD_infiniTUM   (2004-07-13 15:14) [19]


var
 LVItem: TLVItemA;
begin
 for I := 0 to Rows - 1 do
 begin
   FileRead(F, W, SizeOf(W));
   SetLength(S, W);
   FileRead(F, PChar(S)^, W);
   with LVItem do
   begin
     mask := LVIF_TEXT;
     state := 0;
     pszText := @S[1];
     iSubItem := 0;
   end;
   ListView_InsertItem(ListView, LVItem);
   for J := 0 to Cols - 1 do
   begin
     FileRead(F, W, SizeOf(W));
     SetLength(S, W);
     FileRead(F, PChar(S)^, W);
     ListView_SetItemText(ListView, I, J + 1, @S[1]);
   end;
 end;
end;


 
NAlexey ©   (2004-07-13 15:24) [20]

Ну делай так:
 
  with LVItem do
  begin
    mask := LVIF_TEXT;
    state := 0;
    pszText := @S[1];
    iSubItem := 0;
    lParam := Longint(LVItem);
  end;


 
AD_infiniTUM   (2004-07-13 15:29) [21]

Так компилятор не пропустил, я написал так
lParam := Longint(@LVItem);
Но ничего не изменилось.


 
NAlexey ©   (2004-07-13 16:01) [22]

>AD_infiniTUM   (13.07.04 15:29) [21]
Ну одним словом надо подставлять туда уникальное значение для каждого айтема. Например хоть так:

var
 ItemNo: Integer = 0;

procedure ...
var
LVItem: TLVItemA;
begin
for I := 0 to Rows - 1 do
begin
  FileRead(F, W, SizeOf(W));
  SetLength(S, W);
  FileRead(F, PChar(S)^, W);
  with LVItem do
  begin
    mask := LVIF_TEXT;
    state := 0;
    pszText := @S[1];
    iSubItem := 0;
    lParam := ItemNo;
  end;
  ListView_InsertItem(ListView, LVItem);
  for J := 0 to Cols - 1 do
  begin
    FileRead(F, W, SizeOf(W));
    SetLength(S, W);
    FileRead(F, PChar(S)^, W);
    ListView_SetItemText(ListView, I, J + 1, @S[1]);
  end;
  Inc(ItemNo);
 end;
end;


 
AD_infiniTUM   (2004-07-13 16:09) [23]

Все равно не работает. :( Видимо это lParam, и тот, что в функции - это разное...


 
NAlexey ©   (2004-07-13 16:17) [24]

Да, и еще не забывай про LVIF_PARAM. Не просто LVIF_TEXT, а
LVIF_TEXT or LVIF_PARAM.


 
AD_infiniTUM   (2004-07-13 16:23) [25]

NAlexey
Да, точно. Наконец все заработало.
Еще раз спасибо! :)



Страницы: 1 вся ветка

Форум: "WinAPI";
Текущий архив: 2004.08.22;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.51 MB
Время: 0.043 c
3-1090840517
chirchik
2004-07-26 15:15
2004.08.22
TForm.FormActivate - долгая загрузка


14-1091601554
Stany
2004-08-04 10:39
2004.08.22
сетевые глюки винды


14-1091629993
ArMellon
2004-08-04 18:33
2004.08.22
Нужен хороший прокси , какой посоветуете?


4-1089310683
my_name
2004-07-08 22:18
2004.08.22
Форму на панель задач


1-1091793629
Sourse
2004-08-06 16:00
2004.08.22
Как перетаскивать файлы из проводника в программу





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский