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

Вниз

Определение, по какой колонке сделан щелчок в 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 вся ветка

Текущий архив: 2004.08.22;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.044 c
1-1091605973
Молодой
2004-08-04 11:52
2004.08.22
Почему UpperCase не работает с кирилицой и чем её модно заменить?


1-1091703495
Nata
2004-08-05 14:58
2004.08.22
Процесс


14-1091177435
peypivo
2004-07-30 12:50
2004.08.22
Тарифи на мобильную связь.


14-1091355954
dimon_programmer
2004-08-01 14:25
2004.08.22
Как достать темы для XP, подскажите!


1-1091992939
MaxZhirnov
2004-08-08 23:22
2004.08.22
Границы у таблицы через механизм OLE