|
I haven't explained it very well. Basically, I've written a program that writes a .x file using wofstream. But the file doesn't look very pretty so I'm using the directx code I posted to convert it to a better format, so I can also save it as binary or compressed as well as structured text. Basically saves me having to rewrite the program.
I'll close the thread.
|
|
|
|
|
|
You can just stop posting, or edit your original question and add "[closed]" or "[solved]" to the title, and a comment to the effect that you have closed it.
Use the best guess
|
|
|
|
|
That is a recursive function. You may generate assembler output to see the differences between the optimized and unoptimized code.
You should also check for success on all functions that may fail. At least the AddDataObject() return values should be checked and returned upon errors to leave the recursion if something wrent wrong.
|
|
|
|
|
|
Using VS2008 Prof. on Windows8, a Win32 ListView control in Report mode doesn't display any icons at the start of each row. It shows data which I can sort, but no icons.
I'm assuming its some bit or attribute not set somewhere so have to show all the relevant code for someone to see what I'm missing. The list (header)setup code is here (followed by the row insertion code taken out of its loop and then my test code). All error handling removed. I've compared this to an ATL/WTL program that shows the icons and I can't see any difference.
The image list is initialised by the CDeviceImageList constructor which uses the below code to initialize the list:
class CDeviceImageList
{
private:
SP_CLASSIMAGELIST_DATA m_spImageData; public:
CDeviceImageList()
{
RtlZeroMemory(&m_spImageData, sizeof(SP_CLASSIMAGELIST_DATA));
m_spImageData.cbSize = sizeof(SP_CLASSIMAGELIST_DATA);
BOOL b = SetupDiGetClassImageList(&m_spImageData);
if(FALSE == b)
{
assert(!"Failed to aquire class image list");
}
}
operator HIMAGELIST() const throw()
{
return m_spImageData.ImageList;
}
...
ListView setup before the data ...
LVITEM lvItem;
SecureZeroMemory(&lvItem, sizeof(LVITEM));
LVCOLUMN lvCol;
SecureZeroMemory(&lvCol, sizeof(LVCOLUMN));
HWND hList=GetDlgItem(hwnd,IDC_LIST1);
lvCol.pszText=L"Port"; lvCol.mask=LVCF_TEXT;
lvCol.cx=60; lvCol.mask |= LVCF_WIDTH;
lvCol.iSubItem = 0; lvCol.mask |= LVCF_SUBITEM;
lvCol.fmt = HDF_SORTUP; lvCol.fmt |= LVCFMT_LEFT; lvCol.mask |= LVCF_FMT;
int nCol = 0;
nCol = ListView_InsertColumn(hList, lvCol.iSubItem, &lvCol);
lvCol.iSubItem = 1; lvCol.pszText=L"Device"; lvCol.cx=220; nCol = ListView_InsertColumn(hList, lvCol.iSubItem, &lvCol);
lvCol.iSubItem = 2; lvCol.pszText=L"Manufacturer"; lvCol.cx=100; nCol = ListView_InsertColumn(hList, lvCol.iSubItem, &lvCol);
CDeviceImageList cImageList;
HIMAGELIST hImageList = cImageList;
HIMAGELIST hRet = ListView_SetImageList(hList, hImageList, LVSIL_SMALL,);
ListView_SetExtendedListViewStyle(hList, LVS_EX_INFOTIP | LVS_SHOWSELALWAYS);
At this point I can get the image list back from the ListView
The relevant row insertion code, after which I can get the icons, is below but the ListView doesn't display them...
LVITEM lvItem;
SecureZeroMemory(&lvItem, sizeof(LVITEM));
lvItem.mask=LVIF_TEXT; lvItem.cchTextMax = 0;
lvItem.iItem=n; lvItem.iSubItem=0; lvItem.pszText=m_pData[n]->szName;
lvItem.iImage = ImageIndex;
lvItem.mask |= LVIF_IMAGE;
lvItem.lParam=(LPARAM)m_pData[n];
lvItem.mask |= LVIF_PARAM;
HWND hList=GetDlgItem(hwnd,IDC_LIST1);
int nItemIndex = ListView_InsertItem(hList, &lvItem);
lvItem.lParam=0;
lvItem.mask &= ~LVIF_PARAM;
lvItem.iImage = 0;
lvItem.mask &= ~LVIF_IMAGE;
lvItem.iSubItem=1;
lvItem.pszText=(LPTSTR)(LPCTSTR)szData[n][1];
ListView_SetItem(hList, &lvItem);
lvItem.iSubItem=2;
lvItem.pszText=(LPTSTR)(LPCTSTR)szData[n][2];
ListView_SetItem(hList, &lvItem);
After each loop above I can use the following three lines to get the icons (and a few more to display them as proof). But the ListView still refuses to show them...
HWND hList=GetDlgItem(hwnd,IDC_LIST1);
HIMAGELIST hGotList = ListView_GetImageList(hList, LVSIL_SMALL);
HICON hIcon = ImageList_GetIcon(hGotList, ImageIndex, ILD_NORMAL);
modified 17-Jul-13 5:07am.
|
|
|
|
|
Hi,
How are you creating your image list? Are these 32 bit icons?
About Image Lists[^]
Best Wishes,
-David Delaune
|
|
|
|
|
David,
I've now added the code showing the creation of the image list to my question as you're not the only one to ask how it's created or initialized. Basically my CDeviceImageList constructor uses a call to SetupDiGetClassImageList[^].
At the end of my list setup and data initialization I can use the last three lines of code shown to basically: GetDialog, GetListView, and GetIcon followed by a call to
SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM)hIcon); to display in the top-left corner of the dialog the very icon I expect to see in the ListView. which would seem to prove the ImageList in the ListView has the icons.
Are they 32 bit? Not to my knowledge.
I've read the stuff on ImageLists, ListViews etc. until I almost know it by heart.
|
|
|
|
|
CDeviceImageList cImageList;
HIMAGELIST hImageList = cImageList;
HIMAGELIST hRet = ListView_SetImageList(hList, hImageList, LVSIL_SMALL,);
I note that you are using the CDeviceImageList class from this Article[^], in which case you should post your question in the forum at the end of the article to dicuss with the author. Although it looks to me that you have not initialised the object with any icons.
Use the best guess
|
|
|
|
|
Richard,
I've asked the Author of that CDeviceImageList class article you refer to (me) and he's sure the list is initialized - though he cold of course be wrong. I've now added the code from the constructor of this class to the question to show how its initialized.
Tp prove the ListView ImageList is initialized, After setting up the list I can use the three lines show at the end of my question, which are basically,
GetDialog, GetListView, GetIcon , followed by
SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM)hIcon); to display the exactly the icon I'm looking for in the top-left corner of the dialog box.
Which seems to prove the initialization.
|
|
|
|
|
Then that suggests that you are not usiing the correct values when you add an item to the ListView. I would suggest you step through with your debugger to see which icon index is being used when you add an item to the control.
Use the best guess
|
|
|
|
|
Richard,
Stepped through it repeatedly, also side by side comparing it with working ATL/WTL example. I've just typed and run the below test at the end of the loop that fills rows with data where n is the loop variable. I get the LVITEM.iImage which is the index for the row, get a completely new ImageList from the ListView and get the icon from that ImageList successfully and can display it in the dialog top-left corner for any n .
LVITEM lvItemP2;
SecureZeroMemory(&lvItemP2, sizeof(LVITEM));
lvItemP2.mask = LVIF_IMAGE;
lvItemP2.iItem = n;
BOOL bGotItem2 = ListView_GetItem(hList, &lvItemP2);
HIMAGELIST hNewImageList = ListView_GetImageList(hList, LVSIL_SMALL);
if(NULL == hNewImageList)
{
DWORD dwErr = GetLastError();
std::wstring szErr = CWin32ErrToWString()(dwErr);
assert(!"Failed to get image list during test");
}
HICON hIconP2 = ImageList_GetIcon(hNewImageList, lvItemP2.iImage, ILD_NORMAL);
if(NULL == hIconP2)
{
DWORD dwErr = GetLastError();
std::wstring szErr = CWin32ErrToWString()(dwErr);
assert(!"Failed to get icon from image list during test");
}
SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM)hIconP2);
|
|
|
|
|
All well and good, but it does not really address your problem, which is about setting the imagelist and image index correctly in your list view items.
Use the best guess
|
|
|
|
|
I'd say that getting the imagelist from the listview and getting the index into that list from each set of row data and using that index into the imagelist to come up with the expected icon shows I'm setting the imagelist and index correctly and the reason for non-display must be something else.
Stepping through each row item is set with image-index 0x1A, and this is also the value extracted from each row item after setting it.
The imagelist when obtained is of size 0x4A images as is the imagelist extracted from the listview later.
|
|
|
|
|
You are quite right, I mis-read what was happening there. I am afraid I cannot think of anything else to suggest. I have been looking at my own sample ListView program and it works fine, although I do creae the imagelist myself.
Use the best guess
|
|
|
|
|
Richard,
Created an ImageList of the same size from an icon resource and it worked. Same size etc.
Then it hit me, in the WTL project I took this from my CDeviceImageList object was a class variable and in my win32 project I'd declared it in the InitDialog function.
In its constructor CDeviceImageList calls: SetupDiGetClassImageList but in its destructor it calls SetupDiDestroyClassImageList
As it went out of scope ...
Anyway thanks for the help
|
|
|
|
|
I have made similar mistakes more times than I care to recall. Glad you got it sorted.
Use the best guess
|
|
|
|
|
I just ran a very quick test and got it to work; we need to compare code more closely. But that's a job for tomorrow, there's a bottle of Shiraz in the dining room that's calling my name.
Use the best guess
|
|
|
|
|
Hi??
I made 168 columns on my list..
But horizontal scroll is so rough!
I used on CQuickList API... Scroll is working slowly..
CQuickList API is below..
Could you give tips for me how to fix horizontal scroll problem??
[^]
|
|
|
|
|
Please post your question in the forum at the end of the article.
Use the best guess
|
|
|
|
|
I have a listview with custom draw (virtual list)option and i know how to output the items using drawtext() function, but what about the groups? I have googled but Int find anything, all the examples are MFC or without custom draw?! I just want a native example or method about that
thanks
edit.. you got to be kidding with me?!
I found a comment in says it impossible LOL
http://windows-tech.info/14/45a29ec939d2ff8f.php[^]
is that true?
|
|
|
|
|
Have you actually tried implementing groups? As far as I can figure, it makes no difference whether this is 'standard' or owner drawn as the messages and notifications are the same. When and if I get some time I may try it myself.
Use the best guess
|
|
|
|
|
|
i have this code and it works fine.
int fatt(int n)
{
int fattoriale = 1;
if(n==0)
return fattoriale;
else
return fattoriale=n*fatt(n-1);
}
void main(void)
{
printf("%d\n",fatt(10));
fflush(stdin);
getchar();
}
my question is why it works fine also here ?
int fatt(int n)
{
int fattoriale = 1;
if(n==0)
return fattoriale;
else
fattoriale=n*fatt(n-1);
}
void main(void)
{
printf("%d\n",fatt(10));
fflush(stdin);
getchar();
}
in this, there aren't the return in the else.... i am using VS2010 and compile in .c .
thanks
ps: sorry for my english
|
|
|
|
|
In release mode it will create compilation error. It creates compilation error in VS2008. I got compilation error "error C4716: 'fatt' : must return a value".
But in debug mode it works as follows.
In both case contents of EAX register is used as the output of fatt() function. In both case EAX holds the output value, therefore the two versions works correctly in debug mode.
The result of imul is available in eax register and that is the expected result from the fatt function.
Following are the disassembly of two versions of fatt() function. First one with return value and next is without return value.
return fattoriale=n*fatt(n-1);
01182ED2 mov eax,dword ptr [n]
01182ED5 sub eax,1
01182ED8 push eax
01182ED9 call fatt (1181889h)
01182EDE add esp,4
01182EE1 imul eax,dword ptr [n]
01182EE5 mov dword ptr [fattoriale],eax
01182EE8 mov eax,dword ptr [fattoriale]
fattoriale=n*fatt(n-1);
01182F92 mov eax,dword ptr [n]
01182F95 sub eax,1
01182F98 push eax
01182F99 call fatt (11815FAh)
01182F9E add esp,4
01182FA1 imul eax,dword ptr [n]
01182FA5 mov dword ptr [fattoriale],eax
The multiplication in n*fatt(n-1) is done with imul operation. And its output is available in EAX register.
In first version( with return statement), last two instructions perform the following things. Contents of eax is moved to fattoriale and after that the contents of fattoriale is moved to eax( EAX holds the return value, or result of operation).
In second version( without return statement) the last mov is not found. But the output of iMul is in EAX register and therefore the output will be available to caller function through EAX register.
|
|
|
|
|