Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Определение, по какой колонке сделан щелчок в ListView [D7, Win95/98, WinXP]


Страницы:   1 2

AD_infiniTUM ©   (2004-07-12 18:25:00) 

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


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

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


NAlexey   (2004-07-13 16:17:00) [2]

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


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

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


NAlexey   (2004-07-13 16:01:00) [4]

>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 15:29:00) [5]

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


NAlexey   (2004-07-13 15:24:00) [6]

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


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


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:12:00) [8]

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


AD_infiniTUM   (2004-07-13 15:07:00) [9]

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

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


NAlexey   (2004-07-13 14:42:00) [10]

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

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 14:23:00) [11]

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


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


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:11:00) [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 13:41:00) [14]

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

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

вызывай:

ListView_SortItems(Handle, @MySortFunc, 0);

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


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

И еще можно вопрос по 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 11:43:00) [16]

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


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

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


NAlexey   (2004-07-13 11:34:00) [18]

Вот так:

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:30:00) [19]

Нет не полностью. У меня программа на 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:24:00) [20]

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


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо