|
Sliders send NM_CUSTOMDRAW to their parent, like other common controls. With sliders you can custom-draw the thumb, the channel, and the tick marks. If you need a background to show through, subclass the slider and handle WM_ERASEBKGND.
--Mike--
http://home.inreach.com/mdunn/
While I can't be correct on all matters, I can make the reassuring claim that where I am inaccurate, I am at least definitively inaccurate.
your with and
Sonork - 100.10414 AcidHelm
Test out a prerelease build of my Hotfix Checker v2.0! (1
|
|
|
|
|
Hi
is there a way to avoid flickering in a list control if many items are inserted into the list control e.g. by a loop?
thanks in advance
modified 12-Sep-18 21:01pm.
|
|
|
|
|
Send a WM_SETREDRAW message, wParam=FALSE before your loop. After you're done, send it again with wParam=TRUE, then call InvalidateRect() to have the control redraw.
--Mike--
http://home.inreach.com/mdunn/
While I can't be correct on all matters, I can make the reassuring claim that where I am inaccurate, I am at least definitively inaccurate.
your with and
Sonork - 100.10414 AcidHelm
Test out a prerelease build of my Hotfix Checker v2.0! (1
|
|
|
|
|
Hi all, I`ve written some convolution code and managed to get the filters and stuff going fine, the only trouble is the speed! If I so much as use a vector once in the final nested for loop (where it works out the position of the filter with regards to the image) it slows the process down considerably (and I mean considerably - instead of being instant, theres at least a couple of seconds delay). In my code I *need* to access this memory bank at least three times in the final nested for loop (once for Red, Green Blue). Delphi has dynamic arrays which do the job perfectly, I was just wondering what the best way was in VC++? I`ve thought of using pointers, performing a small sum and accessing the pointer at that position, however I`d prefer to use the [] operator as it makes my code that little bit easier to read. Any ideas on better methods for quick access to retrieving data in memory, or as to why my bloody vectors are so slow (I'm using multidimensional vectors, 2-d ones, the location of which is stored in a vector, so I`m actually using a vector of a vector of a vector, but I didn`t think this should slow it down to the amount it is doing? Also my images are quite small, if used a large image I could probably make myself a cup of tea and drink it before it finished!!!) would be much appreciated. Thanks anyway guys,
Alan.
"When I left you I was but the learner, now I am the Master" - Darth Vader
|
|
|
|
|
If your vector exists prior to the loop ( i.e. is not created or modified in terms of size inside the loop ), then I don't see why this would happen. A vector IS a pointer ( a block of continuous memory accessed using pointer offsets ), so you wouldn't get any speed doing it the pointer way, I would think. Having said that, I have always used pointer logic to step through bitmaps myself, and don't consider it hard to read. In other words, I do not speak from experience as I've only done it the alternative way you're proposing in the first place
Christian
After all, there's nothing wrong with an elite as long as I'm allowed to be part of it!! - Mike Burston Oct 23, 2001
Sonork ID 100.10002:MeanManOzI live in Bob's HungOut now
|
|
|
|
|
Depending on what you have in your vector it's quite possible you are copying the data out of the vector instead of accessing it. Can you describe what you are stroing in your vector and how you're accessing it?
Todd Smith
|
|
|
|
|
Yeah I`m only storing integers in the vectors, and as Christian said I can`t understand why the vectors are so slow. However, I`ve since adopted a pointer to an int system, and used a small calculation to work out the position of the relevant integer in the list that is to be used in the convolution stuff. Result - it was sh**loads faster. Just by changing from vectors to pointers made an absolutely massive difference (it was literally the difference between almost instansteously performing the convolution, and waiting a good few seconds for the *exact* same code to run through). I think it must just be because I`m accessing my vectors like so:
...
for (int i=0; i<3; i++)
for (int j=0; j<3; j++)
{
*blue = blue + *(pBits+0) * myVector[a][b];
*green = green + *(pBits+1) * myVector[a][b];
*red = red + *(pBits+2) * myVector[a][b];
}
...
Instead of using myVector, I use pointers to an int (pInt - for arguments sake, and cos I like pInts of strongbow!), as follows : *(pInt+(a*width+b));
And the result is that its loads faster. Hope someone can shed some light on why this is the case, although it doesn`t matter to me now, I`d still like to know why? Thanks guys,
Cheers,
Alan.
P.S. Christian, I think to me, you and the others who are improving their C++ vocabulary every day, reading pointer code is a *relatively* simple task. However, the reason I mentioned this before is that some of my MSc markers are real programming bone heads (the're mathematicians), so I was just thinking that such people might find it *easier* to read and *understand* the vector code, what do you reckon? I`m gonna go with the pointer stuff anyway, it just means extra explanation in the final write up. Cheers though for your advice I do appreciate it.
"When I left you I was but the learner, now I am the Master" - Darth Vader
|
|
|
|
|
I think Tim nailed it when he mentioned copying data out of the vector.
when you do a plain C array with fixed indexes like this, the compiler can generates code that references that value directly (or as an offset from the array base) - ie. it really is equivalent to value = *(arrayBase + offset) . but, with a vector, you're doing something like:
find the data
make a copy of the data
return the data
-c
Smaller Animals Software, Inc.
|
|
|
|
|
Here's the evilness of vector
notice that the [] operator calls begin
reference operator[](size_type _P) {return (*(begin() + _P)); }
and begin CONSTRUCTS! an iterator. That blows.
iterator begin() {return (iterator(0, _Vec.begin())); }
Todd Smith
|
|
|
|
|
This is scary. Here's my test program
int data[10];
int sum = 0;
for (int i = 0; i < 10; i++)
{
sum += data[i];
}
std::vector<int> vdata(10);
for (int j = 0; j < 10; j++)
{
sum += vdata[i];
}
and here's what the difference between the two assembler dumps
sum = data[i] becomes
mov ecx,dword ptr [ebp-3Ch]
mov edx,dword ptr [ebp-38h]
add edx,dword ptr [ebp+ecx*4-34h]
mov dword ptr [ebp-38h],edx
and the vector method sum += vdata[i] becomes
mov eax,dword ptr [ebp-3Ch]
push eax
lea ecx,[ebp-4Ch]
call @ILT+525(std::vector<int,std::allocator<int> >::operator[]) (00401212)
mov ecx,dword ptr [ebp-38h]
add ecx,dword ptr [eax]
mov dword ptr [ebp-38h],ecx
"@ILT+525(std::vector<int,std::allocator<int> >::operator[]) (00401212)"
push ebp
mov ebp,esp
sub esp,44h
push ebx
push esi
push edi
push ecx
lea edi,[ebp-44h]
mov ecx,11h
mov eax,0CCCCCCCCh
rep stos dword ptr [edi]
pop ecx
mov dword ptr [ebp-4],ecx
mov ecx,dword ptr [ebp-4]
call @ILT+475(std::vector<int,std::allocator<int> >::begin) (004011e0)
mov ecx,dword ptr [ebp+8]
lea eax,[eax+ecx*4]
pop edi
pop esi
pop ebx
add esp,44h
cmp ebp,esp
call __chkesp (0040e8b0)
mov esp,ebp
pop ebp
ret 4
"@ILT+475(std::vector<int,std::allocator<int> >::begin) (004011e0)"
push ebp
mov ebp,esp
sub esp,44h
push ebx
push esi
push edi
push ecx
lea edi,[ebp-44h]
mov ecx,11h
mov eax,0CCCCCCCCh
rep stos dword ptr [edi]
pop ecx
mov dword ptr [ebp-4],ecx
mov eax,dword ptr [ebp-4]
mov eax,dword ptr [eax+4]
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
ret
I think I know where the 2 seconds went
Todd Smith
|
|
|
|
|
Thankyou guys, I can now finally put my mind at rest! There was me thinking my new Pentium 4 machines were bunk, when all along it was those bloody vectors! Interesting note you made with regards to the difference between an array of 10 integers and a vector of 10 Todd, even I was suprised by the excessive routine it goes through, geeze. Well, I must say cheers to all you guys for coming up with the solution, at least we all know not to use vectors in a similar situation again, AND we know why.
Alan.
"When I left you I was but the learner, now I am the Master" - Darth Vader
|
|
|
|
|
I've cross posted this into the C++ forum, cause a) it didn't get answered in the COM forum, b) the most knowledgeable people seem to hang out here. This problem was presented to me by a co-worker. It really has me stumped.
In our shop we utilize an application generator "Cool Plex". It builds C++ code and compiles it into dlls. One of its abilities is to include ActiveX controls on a screen. We have written an ActiveX control that dynamically creates a form using Combo box, ListBox and Ms MaskEdBox control. A typical usage might include 2 or 3 instances of each.
The Problem:
Inside our ActiveX we capture the Tab key in each control (control_OnKeyUp) and set focus to the next control, except for the MaskedEdit controls. We get other keys in the KeyUp event, but not the Tab key!!??
If I create a VB app and embed the control in it, the tabbing works as normal, So far, even worse. Now it appears the PLEX generated application is inhibiting the Tab key from getting to the MaskedEdit control which is encapsulated in our ActiveX control. Other encapsulated controls seem to work fine.
It seems to me that these symptoms are mutually exclusive. I don't see how this is possible, but the developer on this project has convinced me that this is what is happening.
1. PLEX container passes (or never gets) Tab key presses to the ActiveX control.
2. PLEX container inhibits the Tab key when the focus inside the ActiveX control is in a MaskedEdit control.
3. I believe the encapsulated control with the focus, gets the events before PLEX, precluding inhibiting the tab key at all.
4. PLEX container has no way to differentiate the encapsulated control with the focus from any other.
5. PLEX container has no way to differentiate the type of control. How could it know that the focus in our Activex control is on a MaskEdBox?
Thanks for the help,
Bill
Thanks for the help,
Bill
|
|
|
|
|
I'm making a dictionary application and I want to know how to map message, when users key-in their vocabulary in combobox and then press enter, with my "Search" procedure. I already mapped button message with my "Search" procedure. I don't know how to use WM_KEYDOWN or ON_WM_KEYDOWN.
Help me, please..
|
|
|
|
|
Hi!!!
Kindly suggest me a resource/web site from where I can get the sample documentation reports of Software projects. I just want to get the idea that how modern professional software documents are been written these days, and how various phases of SDLC are managed.
Sheeraz Khan
|
|
|
|
|
|
Hello, it's me again.
I did all your advises but still have nothing changes ...
If it's possible, can you, please look my code, where is mistake?
all best ..
-----------------------------
void CRegListDlg::QueryKey(HWND hDlg, HKEY hKey)
{
CHAR achKey[MAX_PATH];
CHAR achClass[MAX_PATH] = ""; // buffer for class name
DWORD cchClassName = MAX_PATH; // length of class string
DWORD cSubKeys; // number of subkeys
DWORD cbMaxSubKey; // longest subkey size
DWORD cchMaxClass; // longest class string
DWORD cValues; // number of values for key
DWORD cchMaxValue; // longest value name
DWORD cbMaxValueData; // longest value data
DWORD cbSecurityDescriptor; // size of security descriptor
FILETIME ftLastWriteTime; // last write time
DWORD i, j;
DWORD retCode, retValue;
CHAR achValue[MAX_VALUE_NAME];
DWORD cchValue = MAX_VALUE_NAME;
CHAR achBuff[80];
// Get the class name and the value count.
RegQueryInfoKey(hKey, // key handle
achClass, // buffer for class name
&cchClassName, // length of class string
NULL, // reserved
&cSubKeys, // number of subkeys
&cbMaxSubKey, // longest subkey size
&cchMaxClass, // longest class string
&cValues, // number of values for this key
&cchMaxValue, // longest value name
&cbMaxValueData, // longest value data
&cbSecurityDescriptor, // security descriptor
&ftLastWriteTime); // last write time
// SetDlgItemText(hDlg, IDE_CLASS, achClass);
// SetDlgItemInt(hDlg, IDE_CVALUES, cValues, FALSE);
::SendMessage(GetDlgItem(hDlg, m_list),
LB_ADDSTRING, 0, (LONG) "..");
DWORD dwLength = MAX_PATH;
// Enumerate the child keys, until RegEnumKeyEx fails. Then
// get the name of each child key and copy it into the list box.
SetCursor(LoadCursor(NULL, IDC_WAIT));
for (i = 0, retCode = ERROR_SUCCESS;
retCode != ERROR_NO_MORE_ITEMS; i++)
{
retCode = RegEnumKeyEx(hKey,
i,
achKey,
&dwLength,
NULL,
NULL,
NULL,
&ftLastWriteTime);
if (retCode != (DWORD)ERROR_NO_MORE_ITEMS)
{
::SendMessage(GetDlgItem(hDlg, m_list),
LB_ADDSTRING, 0, (LONG) achKey);
}
dwLength = MAX_PATH;
}
SetCursor(LoadCursor (NULL, IDC_ARROW));
// Enumerate the key values.
SetCursor(LoadCursor(NULL, IDC_WAIT));
if (cValues)
{
for (j = 0, retValue = ERROR_SUCCESS;
j < cValues; j++)
{
cchValue = MAX_VALUE_NAME;
achValue[0] = '\0';
retValue = RegEnumValue(hKey, j, achValue,
&cchValue,
NULL,
NULL, // &dwType,
NULL, // &bData,
NULL); // &bcData
if (retValue != (DWORD) ERROR_SUCCESS &&
retValue != ERROR_INSUFFICIENT_BUFFER)
{
wsprintf (achBuff,
"Line:%d 0 based index = %d, retValue = %d, "
"ValueLen = %d",
__LINE__, j, retValue, cchValue);
// MessageBox (m_hWnd, achBuff, "Debug", MB_OK);
}
achBuff[0] = '\0';
// Add each value to a list box.
if (!lstrlen(achValue))
lstrcpy(achValue, "<no name="">");
wsprintf(achBuff, "%d) %s ", j, achValue);
::SendMessage(GetDlgItem(hDlg,m_list2),
LB_ADDSTRING, 0, (LONG) achBuff);
}
}
SetCursor(LoadCursor(NULL, IDC_ARROW));
}
-------------------------------------------------
and it makes this mistake
: error C2664: 'void __thiscall CWnd::GetDlgItem(int,struct HWND__ ** ) const' : cannot convert parameter 1 from 'struct HWND__ *' to 'int'
This conversion requires a reinterpret_cast, a C-style cast or function-style cast
each time when it goes to "SendMessage" ..
==============
www.design.kg
|
|
|
|
|
GetDlgItem doesn't take a handle to a window as its first parameter, it takes a control ID (ID_MY_BUTTON or something).
-c
Smaller Animals Software, Inc.
|
|
|
|
|
Hello, the codegurus around the world;)
The poster simply misunderstands between CWnd function and Windows API function.
Windows API
HWND GetDlgItem(
HWND hDlg,
int nIDDlgItem
);
And, MFC
CWnd* GetDlgItem( int nID ) const;
void CWnd::GetDlgItem( int nID, HWND* phWnd ) const;
Also, if the poster wants to use WinAPI function in MFC,
we need the global resultion ::GetDlgItem(...);
Please, don't send me your email about your questions directly.
Have a nice day!
Sonork - 100.10571:vcdeveloper
-Masaaki Onishi-
|
|
|
|
|
Yah! And as you can see exactly like this I called this function:
::GetDlgItem
Or I did smf wrong?
==============
www.design.kg
|
|
|
|
|
I found it here:
http://msdn.microsoft.com/library/en-us/sysinfo/regapi_0tq1.asp?frame=true
is it MSDN mistake, that GetDlgItem take a handle to a window as its first parameter?
==============
www.design.kg
|
|
|
|
|
Hello, the codegurus around the world.;)
First of all, you must understand the dif between C and C++ code.
In msdn example, this is written by C code.
In this case, we don't need the global resolution "::".
VOID QueryKey(HWND hDlg, HANDLE hKey)
{
.....
SendMessage(GetDlgItem(hDlg, IDL_LISTBOX),
LB_ADDSTRING, 0, (LONG) "..");
......
}
However, if you use this one in MFC,
void CMyDialog::QueryKey(...)
{
.....
SendMessage(GetDlgItem(hDlg, IDL_LISTBOX),
LB_ADDSTRING, 0, (LONG) "..");
......
.....
SendMessage(::GetDlgItem(hDlg, IDL_LISTBOX),
LB_ADDSTRING, 0, (LONG) "..");
......
or GetDlgItem(IDL_LISTBOX);
}
Please, don't send me your email about your questions directly.
Have a nice day!
Sonork - 100.10571:vcdeveloper
-Masaaki Onishi-
|
|
|
|
|
Like this:
::SendMessage(::GetDlgItem(m_hWnd, m_list),
LB_ADDSTRING, 0, (LONG) "..");
The result is:
: error C2664: 'GetDlgItem' : cannot convert parameter 2 from 'class CString' to 'int'
No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
==============
www.design.kg
|
|
|
|
|
Hello, the codegurus around the world.;)
::SendMessage(::GetDlgItem(m_hWnd, m_list),
LB_ADDSTRING, 0, (LONG) "..");
How did you declare m_list? CString m_list?
GetDlgItem has the second parameter as ID of the control.
So, this should take something like IDC_LIST1.
But, are you sure that you add ListBox (ID: IDC_LIST1) on your dialog box?
Simply copying the code never works unless you have enough knowledge
of both MFC and Win32 program in this case.
Or, to be sure, you add ListBox on your dialog box.
This works.
If you declare CListBox m_list;
::SendMessage(m_list.m_hWnd, LB_ADDSTRING, 0, (LONG) "..");
or
m_list.AddString ("..");
or
m_list.SendMessage(LB_ADDSTRING, 0, (LONG)"..");
Please, don't send me your email about your questions directly.
Have a nice day!
Sonork - 100.10571:vcdeveloper
-Masaaki Onishi-
|
|
|
|
|
Oh, ÎÃÐÎÌÍÎÅ ÑÏÀÑÈÁÎ!
thats in my language mean THANK YOU VERY MUCH! Masaaki
==============
www.design.kg
|
|
|
|
|
"::GetDlgItem(m_hWnd, m_list)" <--- error line
The second parameter should be the control id.
replace m_list with the control id,something like IDLIST01
Nish
Sonork ID 100.9786 voidmain
www.busterboy.org
If you don't find me on CP, I'll be at Bob's HungOut
|
|
|
|
|