Wb-FreeKill Posted March 30, 2005 Share Posted March 30, 2005 Has anyone solved the problem about reading a Listview from a second GUI window, when i do it now the msgbox are empty.. it works when the listview is in the main GUI Link to comment Share on other sites More sharing options...
Fur Posted March 30, 2005 Share Posted March 30, 2005 Yes.. but its not pretty. I made a C++ function in a DLL to do it. // given the hwnd for a listbox, put the contents into a pipe delimited string. however, if there are multiple versions of the same string, append a $$X occurance to the end of each one const char EXPORT *ExtractListContents(HWND hwnd) { static char results[4096]; *results = '\0'; long count = SendMessage(hwnd, LB_GETCOUNT, 0, 0); map<string, int> SeenList; for (long i = 0; i < count; ++i) { char item[256] = ""; SendMessage(hwnd, LB_GETTEXT, i, (long) item); int cnt = 0; map<string, int>::iterator itr = SeenList.find(string(item)); if (itr == SeenList.end()) { SeenList.insert(make_pair(string(item), 1)); } else { cnt = ++(*itr).second; } if (i != 0) strcat(results, "|"); strcat(results, item); if (cnt >= 2) { char tmp[32]; sprintf(tmp, "$$%d", cnt); strcat(results, tmp); } } return results; } Then some AutoIt wrapper functions for getting to the hwnd for the list: ; return the hwnd for the *active* control in the given window Func GetActiveControl($title) WinActivate($title) return ControlGetHandle($title, "", ControlGetFocus($title)) Endfunc Func ExtractListContents($hwnd) Local $foo = DllCall($g_socdll, "str", "ExtractListContents", "hwnd", $hwnd) If @error Then MsgBox(0, "Debug", "Error with DllCall(ExtractListContents)") Endif Return $foo[0] Endfunc I'm still working on the equivalent for a SysTreeView control... Link to comment Share on other sites More sharing options...
Wb-FreeKill Posted March 30, 2005 Author Share Posted March 30, 2005 Hmm, wouldn't it be pretty easy to include in AutoIt so we can use it? i mean, alot of people are waiting for this to be fixed, including me... im on a large program, and have two parts of the program witch really need it, and i can't finish it because of this bug Link to comment Share on other sites More sharing options...
Fur Posted March 30, 2005 Share Posted March 30, 2005 Ooops. I included the code for reading from a regular list box. To read from a ListView32 is just a *teensy* bit harder, since you cannot just grab memory across from one process to another. To work around this minor inconvience, I had to whip out the mega coding kungfu!! You have to actually attach yourself to the other process, so you can allocate memory in its process space to work with. Joy! This version put the contents in the clipboard instead of actually returning the string. And no, sorry, I can't just give you my DLL I'm using! AutoIt Team: feel free to include this whever you like. Example C++ code: expandcollapse popupint EXPORT CopyListViewToClipboard(HWND hwnd, HWND hwndLV) { //fprintf(stderr, "CopyListViewToClipboard(%p, %pd) called\n", hwnd, hwndLV); // If the window under the cursor isn't a ListView, we have nothing to do. if (hwndLV == NULL) return 0; // Get the count of items in the ListView control int nCount = ListView_GetItemCount(hwndLV); // Open a handle to the remote process's kernel object DWORD dwProcessId; GetWindowThreadProcessId(hwndLV, &dwProcessId); HANDLE hProcess = OpenProcess( PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, FALSE, dwProcessId); if (hProcess == NULL) { MessageBox(hwnd, __TEXT("Could not communicate with process"), "CopyListViewToClipboard", MB_OK | MB_ICONWARNING); return 0; } // Prepare a buffer to hold the ListView's data. // Note: Hardcoded maximum of 10240 chars for clipboard data. // Note: Clipboard only accepts data that is in a block allocated with // GlobalAlloc using the GMEM_MOVEABLE and GMEM_DDESHARE flags. HGLOBAL hClipData = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, sizeof(TCHAR) * 10240); LPTSTR pClipData = (LPTSTR) GlobalLock(hClipData); pClipData[0] = 0; // Allocate memory in the remote process's address space LV_ITEM* plvi = (LV_ITEM*) VirtualAllocEx(hProcess, NULL, 4096, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); // Get each ListView item's text data for (int nIndex = 0; nIndex < nCount; nIndex++) { // Initialize a local LV_ITEM structure LV_ITEM lvi; lvi.mask = LVIF_TEXT; lvi.iItem = nIndex; lvi.iSubItem = 0; // NOTE: The text data immediately follows the LV_ITEM structure // in the memory block allocated in the remote process. lvi.pszText = (LPTSTR) (plvi + 1); lvi.cchTextMax = 100; // Write the local LV_ITEM structure to the remote memory block WriteProcessMemory(hProcess, plvi, &lvi, sizeof(lvi), NULL); // Tell the ListView control to fill the remote LV_ITEM structure ListView_GetItem(hwndLV, plvi); // If this is not the first item, add a carriage-return/linefeed if (nIndex > 0) lstrcat(pClipData, __TEXT("\r\n")); // Read the remote text string into the end of our clipboard buffer ReadProcessMemory(hProcess, plvi + 1, &pClipData[lstrlen(pClipData)], 1024, NULL); } // Free the memory in the remote process's address space VirtualFreeEx(hProcess, plvi, 0, MEM_RELEASE); // Cleanup and put our results on the clipboard CloseHandle(hProcess); OpenClipboard(hwnd); EmptyClipboard(); #ifdef UNICODE BOOL fOk = (SetClipboardData(CF_UNICODETEXT, hClipData) == hClipData); #else BOOL fOk = (SetClipboardData(CF_TEXT, hClipData) == hClipData); #endif CloseClipboard(); if (!fOk) { GlobalFree(hClipData); MessageBox(hwnd, __TEXT("Error putting text on the clipboard"), "CopyListViewToClipboard", MB_OK | MB_ICONINFORMATION); } return (fOk) ? 1 : 0; } Link to comment Share on other sites More sharing options...
Wb-FreeKill Posted March 30, 2005 Author Share Posted March 30, 2005 O well, then i have to wait for someone to fix this damn problem.. i REALLY need it! Link to comment Share on other sites More sharing options...
bshoenhair Posted March 30, 2005 Share Posted March 30, 2005 Has anyone solved the problem about reading a Listview from a second GUI window, when i do it now the msgbox are empty.. it works when the listview is in the main GUI<{POST_SNAPBACK}>ControlListView won't work ? Link to comment Share on other sites More sharing options...
layer Posted March 31, 2005 Share Posted March 31, 2005 why can't we use the Dll, if we can view the source?? usually it's vice versa... FootbaG Link to comment Share on other sites More sharing options...
Wb-FreeKill Posted March 31, 2005 Author Share Posted March 31, 2005 why can't we use the Dll, if we can view the source?? usually it's vice versa...<{POST_SNAPBACK}>Without any understandig of c++, i tried to compile the code, and some code are missing, thats why Link to comment Share on other sites More sharing options...
bshoenhair Posted March 31, 2005 Share Posted March 31, 2005 ControlListView won't work ?<{POST_SNAPBACK}>@Wb-FreeKillHave you even tried ControlListView ?It should work. Link to comment Share on other sites More sharing options...
Wb-FreeKill Posted March 31, 2005 Author Share Posted March 31, 2005 @Wb-FreeKillHave you even tried ControlListView ?It should work.<{POST_SNAPBACK}>O im sorry, didn't see your post, ill take a look at it, thx Link to comment Share on other sites More sharing options...
Wb-FreeKill Posted March 31, 2005 Author Share Posted March 31, 2005 O im sorry, didn't see your post, ill take a look at it, thx <{POST_SNAPBACK}>I don't really know how to use this in this case, i do not understand the help file.. Link to comment Share on other sites More sharing options...
bshoenhair Posted March 31, 2005 Share Posted March 31, 2005 I don't really know how to use this in this case, i do not understand the help file..<{POST_SNAPBACK}>What are you trying to retreive from the ListView ? Link to comment Share on other sites More sharing options...
Wb-FreeKill Posted March 31, 2005 Author Share Posted March 31, 2005 What are you trying to retreive from the ListView ?<{POST_SNAPBACK}>Okay, i have two GUI's, Main GUI and Second GUI. The Listview is created in the second GUI, so i would like to have a msgbox telling me what thay Listviewitem im clicking on contains.Like:If $Button Then Msgbox(0,"Test",$GuiCtrlRead($Listview)) ; from the second GUIEndIf Link to comment Share on other sites More sharing options...
bshoenhair Posted March 31, 2005 Share Posted March 31, 2005 Here is a quick example on how to get the Items from a First and second GUI with ControlListview expandcollapse popup#include <GUIConstants.au3> $GUI_1 = GUICreate("listview items",220,250, 0,0,-1,$WS_EX_ACCEPTFILES) GUISetBkColor (0x00E0FFFF) ; will change background color $listviewGUI1 = GuiCtrlCreateListView ("col1 |col2 |col3 ",10,10,200,150);,$LVS_SORTDESCENDING) $button1 = GuiCtrlCreateButton ("GUI1GetAllItems",10,170,100,20) $button2 = GuiCtrlCreateButton ("GUI2GetAllItems",110,170,100,20) $item1=GuiCtrlCreateListViewItem("GUI1item1|GUI1item2|GUI1item3",$listviewGUI1) $item2=GuiCtrlCreateListViewItem("GUI1item2_1|GUI1item2_2|GUI1item2_3",$listviewGUI1) $item3=GuiCtrlCreateListViewItem("GUI1item3_1|GUI1item3_2|GUI1item3_3",$listviewGUI1) GuiSetState() $GUI_2 = GUICreate("listview items",220,250, 300,0,-1,$WS_EX_ACCEPTFILES) GUISetBkColor (0x00E0FFFF) ; will change background color $listviewGUI2 = GuiCtrlCreateListView ("col1 |col2 |col3 ",10,10,200,150);,$LVS_SORTDESCENDING) GuiCtrlCreateListViewItem("GUI2item1|GUI2item2|GUI2item3",$listviewGUI2) GuiCtrlCreateListViewItem("GUI2item2_1|GUI2item2_2|GUI2item2_3",$listviewGUI2) GuiCtrlCreateListViewItem("GUI2item3_1|GUI2item3_2|GUI2item3_3",$listviewGUI2) GuiSetState() Do $msg = GuiGetMsg () Select Case $msg = $button1 $ItemCount = ControlListView ( $GUI_1, "", "SysListView321","GetItemCount") For $i = 0 To $ItemCount -1 MsgBox(0,"",ControlListView ( $GUI_1, "", "SysListView321","GetText", $i)) Next Case $msg = $button2 $ItemCount = ControlListView ( $GUI_2, "", "SysListView321","GetItemCount") For $i = 0 To $ItemCount -1 MsgBox(0,"",ControlListView ( $GUI_2, "", "SysListView321","GetText", $i)) Next EndSelect Until $msg = $GUI_EVENT_CLOSE Link to comment Share on other sites More sharing options...
bshoenhair Posted March 31, 2005 Share Posted March 31, 2005 Try this: #include <GUIConstants.au3> $GUI_1 = GUICreate("listview items",220,250, 0,0,-1,$WS_EX_ACCEPTFILES) GUISetBkColor (0x00E0FFFF) ; will change background color $listviewGUI1 = GuiCtrlCreateListView ("col1 |col2 |col3 ",10,10,200,150);,$LVS_SORTDESCENDING) $button1 = GuiCtrlCreateButton ("GUI1GetSelected",10,170,100,20) $button2 = GuiCtrlCreateButton ("GUI2GetSelected",110,170,100,20) GuiCtrlCreateListViewItem("GUI1item1|GUI1item2|GUI1item3",$listviewGUI1) GuiCtrlCreateListViewItem("GUI1item2_1|GUI1item2_2|GUI1item2_3",$listviewGUI1) GuiCtrlCreateListViewItem("GUI1item3_1|GUI1item3_2|GUI1item3_3",$listviewGUI1) GuiSetState() $GUI_2 = GUICreate("listview items",220,250, 300,0,-1,$WS_EX_ACCEPTFILES) GUISetBkColor (0x00E0FFFF) ; will change background color $listviewGUI2 = GuiCtrlCreateListView ("col1 |col2 |col3 ",10,10,200,150);,$LVS_SORTDESCENDING) GuiCtrlCreateListViewItem("GUI2item1|GUI2item2|GUI2item3",$listviewGUI2) GuiCtrlCreateListViewItem("GUI2item2_1|GUI2item2_2|GUI2item2_3",$listviewGUI2) GuiCtrlCreateListViewItem("GUI2item3_1|GUI2item3_2|GUI2item3_3",$listviewGUI2) GuiSetState() Do $msg = GuiGetMsg () Select Case $msg = $button1 If ControlListView ( $GUI_1, "", "SysListView321","GetSelectedCount") > 0 Then MsgBox(0,"",ControlListView ( $GUI_1, "", "SysListView321","GetText", ControlListView ( $GUI_1, "", "SysListView321","GetSelected"))) EndIf Case $msg = $button2 If ControlListView ( $GUI_2, "", "SysListView321","GetSelectedCount") > 0 Then MsgBox(0,"",ControlListView ( $GUI_2, "", "SysListView321","GetText", ControlListView ( $GUI_2, "", "SysListView321","GetSelected"))) EndIf EndSelect Until $msg = $GUI_EVENT_CLOSE Link to comment Share on other sites More sharing options...
Wb-FreeKill Posted March 31, 2005 Author Share Posted March 31, 2005 Well that looks pretty easy, thx for your help! Link to comment Share on other sites More sharing options...
GaryFrost Posted July 23, 2005 Share Posted July 23, 2005 see this post:#94887 SciTE for AutoItDirections for Submitting Standard UDFs Don't argue with an idiot; people watching may not be able to tell the difference. Link to comment Share on other sites More sharing options...
t0ddie Posted July 23, 2005 Share Posted July 23, 2005 all i do is save the data added to the list into an array, then i read from the array and not the list. works for me. Valik Note Added 19 October 2006 - 08:38 AMAdded to warn level I just plain don't like you. Link to comment Share on other sites More sharing options...
GaryFrost Posted July 23, 2005 Share Posted July 23, 2005 No need to do that anymore, the problem has been fixed, see my previous post for example. SciTE for AutoItDirections for Submitting Standard UDFs Don't argue with an idiot; people watching may not be able to tell the difference. Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now