Jump to content
Sign in to follow this  
FuryCell

getsubitemtext

Recommended Posts

FuryCell

I'm working on a dll to sort listviews faster and I need the following code converted to c. I'm new to c and am not sure how to go about doing this. To make matters worse when I google for c it turns up C++.

Func GetSubItemText($nCtrlID, $nItemID, $nColumn)
    Local $stLvfi = DllStructCreate("uint;ptr;int;int[2];int")
    Local $nIndex, $stBuffer, $stLvi, $sItemText

    DllStructSetData($stLvfi, 1, $LVFI_PARAM)
    DllStructSetData($stLvfi, 3, $nItemID)

    $stBuffer = DllStructCreate("char[260]")

    $nIndex = GUICtrlSendMsg($nCtrlID, $LVM_FINDITEM, -1, DllStructGetPtr($stLvfi));

    $stLvi = DllStructCreate("uint;int;int;uint;uint;ptr;int;int;int;int")

    DllStructSetData($stLvi, 1, $LVIF_TEXT)
    DllStructSetData($stLvi, 2, $nIndex)
    DllStructSetData($stLvi, 3, $nColumn)
    DllStructSetData($stLvi, 6, DllStructGetPtr($stBuffer))
    DllStructSetData($stLvi, 7, 260)

    GUICtrlSendMsg($nCtrlID, $LVM_GETITEMA, 0, DllStructGetPtr($stLvi));

    $sItemText = DllStructGetData($stBuffer, 1)

    $stLvi = 0
    $stLvfi = 0
    $stBuffer = 0

    Return $sItemText
EndFunc   ;==>GetSubItemText

HKTunes:Softpedia | GoogleCodeLyricToy:Softpedia | GoogleCodeRCTunes:Softpedia | GoogleCodeMichtaToolsProgrammer n. - An ingenious device that turns caffeine into code.

Share this post


Link to post
Share on other sites
monoceres

Why can't you use C++?

Also, it's not very complicated code. Read up on structs and you should be able to do it yourself.

Edited by monoceres

Broken link? PM me and I'll send you the file!

Share this post


Link to post
Share on other sites
wraithdu

Try:

#include <commctrl.h>

DLL_EXPORT BOOL GetSubItemText(HWND hCtrl, int nItemID, int nColumn, LPWSTR pTextBuff)
{
    LVFINDINFO lvfi = {0};
    lvfi.flags = LVFI_PARAM;
    lvfi.lParam = nItemID;
    LRESULT nIndex = SendMessageW(hCtrl, LVM_FINDITEMW, -1, (LPARAM) &lvfi);
    if (nIndex == -1) return FALSE;
    
    LVITEM lvi = {0};
    lvi.mask = LVIF_TEXT;
    lvi.iItem = nIndex;
    lvi.iSubItem = nColumn;
    lvi.pszText = pTextBuff;
    lvi.cchTextMax = 260;
    return SendMessageW(hCtrl, LVM_GETITEMW, 0, (LPARAM) &lvi);
}

Provide the handle to your control in the first parameter, and your buffer in the last parameter. The function returns a BOOL, TRUE or FALSE (1 or 0).

Edited by wraithdu

Share this post


Link to post
Share on other sites
Valik

I'm new to c and am not sure how to go about doing this.

This is the part where you (should) stop and try to learn the language first without the Windows-specific stuff.

Share this post


Link to post
Share on other sites
wraithdu

Quickie example:

#include <GuiListView.au3>
#include <Array.au3>

$gui = GUICreate("LV_TEST", 400, 400)
$lv = GUICtrlCreateListView("first column|second column", 10, 10, 350, 350)
Dim $aID[1]
For $i = 0 To 4
    ; with internal funcs, the returned ID is the lParam
    _ArrayAdd($aID, GUICtrlCreateListViewItem("item " & $i + 1 & "|subitem " & $i + 1, $lv))
Next
;~ GUISetState()

$dll = DllOpen("test_dll.dll")
$hlv = GUICtrlGetHandle($lv)
For $i = 1 To (UBound($aID) - 1)
    For $j = 0 To 1
        $ret = DllCall($dll, "int:cdecl", "GetSubItemText", "hwnd", $hlv, "int", $aID[$i], "int", $j, "wstr", "")
        ConsoleWrite("item: " & $i & ", subitem: " & $j & ", text: " & $ret[4] & @CRLF)
    Next
Next
DllClose($dll)

;~ Do
;~ Until GUIGetMsg() = -3

Share this post


Link to post
Share on other sites
FuryCell

Thanks wraith. The code works great. Now im working on the function to sort the list view however it hard crashes. I'm probably doing a lot of things terribly wrong.

DLLIMPORT int LVSort(HWND hCtrl,int item1,int item2, int column)
{
          LPWSTR pTextBuff1="";
          LPWSTR pTextBuff2="";
          char* val1=GetSubItemText(hCtrl,item1,column,pTextBuff1);
          char* val2=GetSubItemText(hCtrl,item2,column,pTextBuff2);
            if (val1 < val2) return -1;
            return 1;
}

I'm trying to convert this.

Func LVSort($hWnd, $nItem1, $nItem2, $nColumn)
    $val1 = GetSubItemText($hWnd, $nItem1, $nColumn)
    $val2 = GetSubItemText($hWnd, $nItem2, $nColumn)
    
    If $val1 < $val2 Then
        Return -1   ; Put item2 before item1
    ElseIf $val1 > $val2 Then
        Return 1    ; Put item2 behind item1
    EndIf
EndFunc   ;==>LVSort

Also @Valik. You are probably right. I'm learning little by little. I just really want to get this working since I need it for a project I'm working on in au3.

Edited by P5ych0Gigabyte

HKTunes:Softpedia | GoogleCodeLyricToy:Softpedia | GoogleCodeRCTunes:Softpedia | GoogleCodeMichtaToolsProgrammer n. - An ingenious device that turns caffeine into code.

Share this post


Link to post
Share on other sites
monoceres

DLLIMPORT int LVSort(HWND hCtrl,int item1,int item2, int column)
{
 LPWSTR pTextBuff1="";
 LPWSTR pTextBuff2="";
 char* val1=GetSubItemText(hCtrl,item1,column,pTextBuff1);
 char* val2=GetSubItemText(hCtrl,item2,column,pTextBuff2);
 if (val1 < val2) return -1;
 return 1;
}

Stop. Now.

That was the perfect example of why you really should learn the language before diving into it with your head first.

The code may look good to you but for those of us who know C we only see really, really messed up incorrect code that isn't even close to work.

So, go read at least an Internet tutorial on the subject.

Edited by monoceres

Broken link? PM me and I'll send you the file!

Share this post


Link to post
Share on other sites
wraithdu

Yikes...

Here's a great C primer. The download isn't working for me right now, but you can probably find it elsewhere on the net if it doesn't come back soon.

http://www.mindviewinc.com/CDs/ThinkingInC/

(ThinkingInC-Beta3.zip)

Then go here: http://www.cplusplus.com/doc/tutorial/

Read everything.

Edited by wraithdu

Share this post


Link to post
Share on other sites
Valik

Since it's not mentioned so far... why learn C when you can just learn C++?

Share this post


Link to post
Share on other sites
FuryCell

Yikes...

Here's a great C primer. The download isn't working for me right now, but you can probably find it elsewhere on the net if it doesn't come back soon.

http://www.mindviewinc.com/CDs/ThinkingInC/

(ThinkingInC-Beta3.zip)

Then go here: http://www.cplusplus.com/doc/tutorial/

Read everything.

Thanks for the info. I'll take a look at all that.

Since it's not mentioned so far... why learn C when you can just learn C++?

I had trouble learning c++ but that was years ago. I'm probablly better off with C++ soi im gonna go with that.


HKTunes:Softpedia | GoogleCodeLyricToy:Softpedia | GoogleCodeRCTunes:Softpedia | GoogleCodeMichtaToolsProgrammer n. - An ingenious device that turns caffeine into code.

Share this post


Link to post
Share on other sites
wraithdu

Since it's not mentioned so far... why learn C when you can just learn C++?

When I was reading about Thinking in C/C++, the author mentioned it was a good idea to have at least a basic understanding of C before beginning to learn C++ (ie read Thinking in C first). Just thought I'd pass on that recommendation.

Share this post


Link to post
Share on other sites
Valik

I do not agree with the author. I find C to be... annoying. Learning C first is just going to teach bad habits that will need to be broken. The problem is a new programmer isn't going to know they are bad habits and by the time they learn that they may be resistant to changing them.

Share this post


Link to post
Share on other sites
monoceres

I do not agree with the author. I find C to be... annoying. Learning C first is just going to teach bad habits that will need to be broken. The problem is a new programmer isn't going to know they are bad habits and by the time they learn that they may be resistant to changing them.

I agree C is an annoying language, but I still think it's a really good idea to at least have basic understanding of C before learning C++. Why? Because way too often when people begin with C++ they learn STL right away which makes stuff kinda messed up.

For example, I'm currently taking a course in C++ at the university, things have been focusing on STL pretty much which makes stuff like this happen:

My friend sitting next to me had trouble compiling his code, it looked like this:

if ("somestring" == argv)

Since he had only used std::string before he thought that std::string was the only way to deal with strings in C++. It was annoying to try to explain how argv was a pointer to a pointer or an array of arrays or that the string literal was a constant char array.

Same thing happened when people tried to use arrays but failed because they couldn't modify it like they did with std::list and std::vector.

Edited by monoceres

Broken link? PM me and I'll send you the file!

Share this post


Link to post
Share on other sites
FuryCell

So I am finally diving into C++. I got my c dll working btw. My code is probably hideous though. :)

DLLIMPORT int LVSort(HWND hCtrl,int item1,int item2, int column,LPWSTR pTextBuff1,LPWSTR pTextBuff2)
{
  int i;
  GetSubItemText(hCtrl,item1,column,pTextBuff1);
  GetSubItemText(hCtrl,item2,column,pTextBuff2);
  for(i = 0; pTextBuff1[ i ]; i++)
    pTextBuff1[i] = tolower(pTextBuff1[ i ]);
  for(i = 0; pTextBuff2[ i ]; i++)
    pTextBuff2[i] = tolower(pTextBuff2[ i ]);
  return strcmp(pTextBuff2,pTextBuff1);
}

Quick question how would i define pTextBuff1 and 2 without having them as perimeters. The following code causes a hard crash of au3.

DLLIMPORT int LVSort(HWND hCtrl,int item1,int item2, int column)
{
  int i;
  LPWSTR pTextBuff1;
  LPWSTR pTextBuff2;
  GetSubItemText(hCtrl,item1,column,pTextBuff1);
  GetSubItemText(hCtrl,item2,column,pTextBuff2);
  for(i = 0; pTextBuff1[ i ]; i++)
    pTextBuff1[i] = tolower(pTextBuff1[ i ]);
  for(i = 0; pTextBuff2[ i ]; i++)
    pTextBuff2[i] = tolower(pTextBuff2[ i ]);
  return strcmp(pTextBuff2,pTextBuff1);
}
Edited by P5ych0Gigabyte

HKTunes:Softpedia | GoogleCodeLyricToy:Softpedia | GoogleCodeRCTunes:Softpedia | GoogleCodeMichtaToolsProgrammer n. - An ingenious device that turns caffeine into code.

Share this post


Link to post
Share on other sites
Valik

Ugh, please excuse me while I go stab my eyes.

Really, you need to either 1) Give up learning C++ if you aren't willing to do it right; 2) Do it right and read some of the books in the sticky thread on books (thread by me).

Share this post


Link to post
Share on other sites
FuryCell

ok. I'm gonna read the data in the sticky and I got a copy of C++ for dummies. One last request though. Can someone please convert this to C++. Its exactly whats needed for sorting LVs really fast. Let me know if i am out of line requesting C++ code here.

; #FUNCTION# ====================================================================================================================
; Name...........: _GUICtrlListView_SimpleSort
; Description ...: Sorts a list-view control (limited)
; Syntax.........: _GUICtrlListView_SimpleSort($hWnd, ByRef $vDescending, $iCol)
; Parameters ....: $hWnd        - Handle to the control
;                  $vDescending - Can be:
;                  | True       - Sort Descending
;                  | False      - Sort Ascending
;                  +Array       - With the following format:
;                  |[0]         - First Column
;                  |[1]         - Second Column
;                  |[n]         - Last Column
; Return values .: None
; Author ........: Gary Frost (gafrost)
; Modified.......:
; Remarks .......: This is a basic sort fuction, for advanced sort see GUICtrlRegisterListViewSort
; Related .......: GUICtrlRegisterListViewSort
; Link ..........;
; Example .......; Yes
; ===============================================================================================================================
Func _GUICtrlListView_SimpleSort($hWnd, ByRef $vDescending, $iCol)
    If $Debug_LV Then _GUICtrlListView_ValidateClassName($hWnd)
    Local $x, $Y, $Z, $b_desc, $columns, $items, $v_item, $temp_item, $iFocused = -1
    Local $SeparatorChar = Opt('GUIDataSeparatorChar')
    If _GUICtrlListView_GetItemCount($hWnd) Then
        If (IsArray($vDescending)) Then
            $b_desc = $vDescending[$iCol]
        Else
            $b_desc = $vDescending
        EndIf
        $columns = _GUICtrlListView_GetColumnCount($hWnd)
        $items = _GUICtrlListView_GetItemCount($hWnd)
        For $x = 1 To $columns
            $temp_item = $temp_item & " " & $SeparatorChar
        Next
        $temp_item = StringTrimRight($temp_item, 1)
        Local $a_lv[$items][$columns + 1], $i_selected
        $i_selected = StringSplit(_GUICtrlListView_GetSelectedIndices($hWnd), $SeparatorChar)
        For $x = 0 To UBound($a_lv) - 1 Step 1
            If $iFocused = -1 Then
                If _GUICtrlListView_GetItemFocused($hWnd, $x) Then $iFocused = $x
            EndIf
            _GUICtrlListView_SetItemSelected($hWnd, $x, False)
;~          _GUICtrlListView_SetItemState($hWnd, $x, 0, BitOR($LVIS_SELECTED, $LVIS_FOCUSED))
            For $Y = 0 To UBound($a_lv, 2) - 2 Step 1
                $v_item = StringStripWS(_GUICtrlListView_GetItemText($hWnd, $x, $Y), 2)
                If (StringIsFloat($v_item) Or StringIsInt($v_item)) Then
                    $a_lv[$x][$Y] = Number($v_item)
                Else
                    $a_lv[$x][$Y] = $v_item
                EndIf
            Next
            $a_lv[$x][$Y] = $x
        Next
        _ArraySort($a_lv, $b_desc, 0, 0, $iCol)
        For $x = 0 To UBound($a_lv) - 1 Step 1
            For $Y = 0 To UBound($a_lv, 2) - 2 Step 1
;~              _GUICtrlListViewSetItemText($hWnd, $x, $Y, $a_lv[$x][$Y])
                _GUICtrlListView_SetItemText($hWnd, $x, $a_lv[$x][$Y], $Y)
            Next
            For $Z = 1 To $i_selected[0]
                If $a_lv[$x][UBound($a_lv, 2) - 1] = $i_selected[$Z] Then
                    If $a_lv[$x][UBound($a_lv, 2) - 1] = $iFocused Then
                        _GUICtrlListView_SetItemSelected($hWnd, $x, True, True)
                    Else
                        _GUICtrlListView_SetItemSelected($hWnd, $x, True)
                    EndIf
;~                  _GUICtrlListView_SetItemState($hWnd, $x, $LVIS_SELECTED, BitOR($LVIS_SELECTED, $LVIS_FOCUSED))
;~                  If $a_lv[$x][UBound($a_lv, 2) - 1] = $iFocused Then _GUICtrlListView_SetItemState($hWnd, $x, $LVIS_FOCUSED, $LVIS_FOCUSED)
                    ExitLoop
                EndIf
            Next
        Next
        If (IsArray($vDescending)) Then
            $vDescending[$iCol] = Not $b_desc
        Else
            $vDescending = Not $b_desc
        EndIf
    EndIf
EndFunc   ;==>_GUICtrlListView_SimpleSort

HKTunes:Softpedia | GoogleCodeLyricToy:Softpedia | GoogleCodeRCTunes:Softpedia | GoogleCodeMichtaToolsProgrammer n. - An ingenious device that turns caffeine into code.

Share this post


Link to post
Share on other sites
Richard Robertson

I'll give you a hint. LPWSTR is a pointer.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×