|
Hi Steve,
maybe my response to another question might
help you, unless you are the same person i originally replied to
Alwin
|
|
|
|
|
Hi,
I have a very spurious problem. I have a MFC Grid (thanks, Chris!) in a view in a MFC app. I want the grid to change the sort order of the items when the user clicks the header. So if the first item is selected when the header is clicked the grid should reverse the items and scroll down to the last item.
I have implemented the scrolling part this way:
void CMyGridCtrlDerivative::SetNewPosition(int nPos)
{
...code
SetScrollPos32(SB_VERT, nPos * GetRowHeight(nPos));
SendMessage(WM_VSCROLL, SB_THUMBPOSITION, 0);
}
where nPos is the new position (linenumber) to scroll to. All items have the same height, so I use the height of the nPos'th item to convert from linenumber to pixel.
This does not work when I execute the program with Go (F5) - the items are reversed after click on header but the grid does not scroll down, and the thumb position on the scroll bar is not changed. However, if I put a breakpoint on the SendMessage-line, and the execute with Go (F5) and press Go (F5) again when the app breaks, then everything works as planned! I don't change anything during the break, I just press F5.
I have tried to put a pause (Sleep(5000)) between the SetScrollPos32 and SendMessage calls, didn't work.
I changed the SendMessage to a PostMessage, didn't work.
What the f*** is going on?????
Cheers
Steen.
"To claim that computer games influence children is ridiculous. If Pacman had influenced children born in the 80'ies we would see a lot of youngsters running around in dark rooms eating pills while listening to monotonous music"
|
|
|
|
|
It is not a good idea to handle scrolling by sending WM_xSCROLL messages, as there many problem will arise, as you call SetScrollPos32 and then send WM_VSCROLL + SB_THUMBPOSITION which is processed internally so that it interferes with previous call of SetScrollPos32. Also read the excellent book by Richter on Win32 programming, namely - section on message queuing. You'd better deal with functions that perform necessary operations when WM_xSCROLL messages are received. Just an example:
<br />
void CMyGridCtrlDerivative::SetNewPosition(int nPos)<br />
{ <br />
...code <br />
SetScrollPos32(SB_VERT, nPos * GetRowHeight(nPos)); <br />
DoProcessWmVscroll(SB_THUMBPOSITION);<br />
}<br />
|
|
|
|
|
If you put a breakpoint, it totally changes both the message queue and the paint workflow ( additional Invalidate() and Update() methods, plus WM_PAINT commands will be sent to your window(s) ).
That's due to the app switch to the breakpoint. And that's the reason the behavior of your app foes not change if you post some messages or add Sleep().
MS quote (http://www.microsoft.com/ddk) : As of September 30, 2002, the Microsoft® Windows® 2000 DDK, the Microsoft Windows 98 DDK, and the Microsoft Windows NT® 4.0 DDK will no longer be available for purchase or download on this site. Support for development will ship at the same time as the Windows XP Service Pack 1 (SP1) release.
|
|
|
|
|
Thanks for the replies. I finaly figured out what was wrong, and as you suggested the breakpoint-thing was due to a WM_PAINT being send to the grid between the statements.
The problem was that SetScrollPos32 uses SetScrollInfo, where you can set the scroll bar position but not the thumb track position. The WM_VSCROLL handler in the grid would read the thumb track position (and not the scroll bar position) in response to SB_THUMBPOSITION and this would in turn set the first item to be displayed to a wrong value. The WM_PAINT message send by the break/continue event would invoke OnDraw, where the first item to be displayed would be set from the scroll bar position (and not the thumb track position), hence this worked.
I just removed the SendMessage(WM_VSCROLL, SB_THUMBPOSITION, 0) and replaced it with a call to Invalidate() - and then everything worked.
Thanks for yourhelp
Cheers
Steen.
"To claim that computer games influence children is ridiculous. If Pacman had influenced children born in the 80'ies we would see a lot of youngsters running around in dark rooms eating pills while listening to monotonous music"
|
|
|
|
|
Hi...
Simple Question:
- I want to move a dialog box on the middle of CMyView. The dialog box is a member of CMyView...
I already use CWnd::MoveWindow(), GetWindowRect(), etc...
But the dialog box don't appear on the middle...
thank for all advices!!!
Hello World!!!
from Raphaël
|
|
|
|
|
Use GetClientRect instead
Cheers
Steen.
"To claim that computer games influence children is ridiculous. If Pacman had influenced children born in the 80'ies we would see a lot of youngsters running around in dark rooms eating pills while listening to monotonous music"
|
|
|
|
|
Hi,
In a dialog-based application, i have a listbox to show the results of
some calculation and a progressbar to show the finishment of the task.
The problem is:
(1) the dialog window cannot be re-maximized when minimum is implemented under the case of the runing of the process.
(2) How to abort the process including the stop of the adding strings to listbox and stop the progressbar?
Thanks in advance!
chen
|
|
|
|
|
You should do the calculation in a worker thread or a process in an extreme case. Using a worker thread will allow the user to cancel the calculation.
Kuphryn
|
|
|
|
|
You will have to check the message queue frequently using PeekMessage. See for example MSDN KB Q74795, and I vaguely remember an article here on CP about it too.
PeekMessage is much easier than worker threads.
Cheers
Steen.
"To claim that computer games influence children is ridiculous. If Pacman had influenced children born in the 80'ies we would see a lot of youngsters running around in dark rooms eating pills while listening to monotonous music"
|
|
|
|
|
i have process id and want to get main window hwnd how to get it.
r00d0034@yahoo.com
|
|
|
|
|
|
I think this might work for you, although it doesn't feel very elegant. Try looking at the Win32 API EnumWindows(). You define a callback function and pass that into EnumWindows(). For every top-level window open on the desktop, you'll get one call into your function, which hands you the HWND of that window and a user-defined field.
With the HWND, you can then call GetWindowThreadProcessId() to try and match to your already-known Process ID. So you'd set it up so that your callback function will keep churning (by setting the return value to TRUE) until it finds the right Process ID. Use the lParam field in EnumWindows to pass along an information struct that holds your ProcessID and the output HWND.
There's probably a cleaner way to do this, but this should get you on the right track. Here's some pseudo-code:
typedef struct
{
DWORD dwProcessID;
HWND hWnd;
} ENUM_PARAM, *LPENUM_PARAM;
BOOL CALLBACK cbEnumWindows( HWND hwnd, LPARAM lParam )
{
LPENUM_PARAM lpEnum = static_cast< LPENUM_PARAM >( lParam );
if( lpEnum )
{
DWORD dwProcessID = 0;
GetWindowThreadProcessId( hwnd, &dwProcessID );
if( dwProcessID == lpEnum->dwProcessID )
{
lpEnum->hWnd = hwnd;
return FALSE;
}
}
return TRUE;
}
int main( int argc, char *argv[] )
{
ENUM_PARAM EnumParam;
EnumParam.dwProcessID = 1234;
EnumParam.hWnd = NULL;
EnumWindows( cbEnumWindows, static_cast< LPARAM >( &EnumParam ) );
if( EnumParam.hWnd )
{
}
}
</code>
Ty
|
|
|
|
|
const int ca(200);
int &cb=*((int*)&ca);
cb=2400;
cout<<"ca="<
|
|
|
|
|
The compiler is probably optimizing because ca is declared const. The compiler can replace any references to ca and directly insert 200.
--Mike--
Just released - RightClick-Encrypt v1.4 - Adds fast & easy file encryption to Explorer
My really out-of-date homepage
Sonork-100.19012 Acid_Helm
|
|
|
|
|
Your reply sounds reasonable, but both the varibale of 'ca' and 'cb' have same address in memory, but their value is different, I just can't unstand it, it must be somewhere else for 'ca' or 'cb', is that correct!
|
|
|
|
|
cadinfo wrote:
, but both the varibale of 'ca' and 'cb' have same address in memory
After the compiler optimization, 'ca' has NO address in memory any more. It simply is the value '200' known at compile time.
You promised not to change this value by declaring it const, remember?
So the compiler can replace every access to 'ca' by the value '200' at compile time.
In effect, this is a little like a precompiler #define, in that both methods don't make a variable.
|
|
|
|
|
jhwurmbach wrote:
,After the compiler optimization, 'ca' has NO address in memory any more.
but in debug mode or use
cout<<"&ca="<<&ca<<"\t&cb="<<cb<<endl;
you will find address of ca is same to cb, and in debug time the value of ca will change to new value, but when output it return to '200'
|
|
|
|
|
Well, I did look at the assembly-code, after tracing did not reveal why '2400' is changed to '200' in output:
16: cout<<"ca="<<ca<<"\tcb="<<cb<<endl;
004017BE push offset @ILT+195(std::endl) (004010c8)
004017C3 mov edx,dword ptr [ebp-8]
004017C6 mov eax,dword ptr [edx]
004017C8 push eax
004017C9 push offset string "\tcb=" (0046e020)
004017CE push 0C8h
004017D3 push offset string "ca=" (0046e01c)
004017D8 push offset std::cout (0047c0c0)
004017DD call @ILT+640(std::operator<<) (00401285)
004017E2 add esp,8
004017E5 mov ecx,eax
004017E7 call @ILT+250(std::basic_ostream<char,std::char_traits<char> >::operator<< ) (004010ff)
At address 004017CE you see how the code inserts the '200' (0C8h) into the output stream and does not access the variable at [ebp-4].
Some sort of optimisation, even in debug mode.
But you can't blame the compiler, after all you *promised* that 'ca' would not change!
|
|
|
|
|
I have an MFC MDI App. In this I want to copy a bmp from Folder1 into folder2 .How does one do this?
Thanks,
ns
|
|
|
|
|
You could use CopyFile(), look it up in MSDN...
- Anders
Money talks, but all mine ever says is "Goodbye!"
|
|
|
|
|
SHFileOperation could find some use as well
|
|
|
|
|
I created a new database using ADOX. When I go to add ecords to it, they are added haphazardly, not in order. THe latest one might be in the middle somewhere...
How do I ensure that they get added in order?
Heres my code:
try
{
ADO::_RecordsetPtr rsBlob (__uuidof(ADO::Recordset) );
m_pCommand->CommandText="SELECT * FROM tblTest" ;
rsBlob->CursorLocation = ADO::adUseClient;
rsBlob->Open ((IDispatch *) m_pCommand, vtMissing, ADO::adOpenKeyset,
ADO::adLockOptimistic, -1);
rsBlob->AddNew();
rsBlob->Fields->Item["A_Image"]->Value = bstrFile;
char* charID = new char[strID.GetLength()+1];
strcpy(charID, strID);
rsBlob->Fields->Item["MINE_TYPE"]->Value = charID;
delete[] charID;
}
Thanks for helping,
ns
|
|
|
|
|
The SQL database does not guarantees, that it stores records in particular order (even if it often does). It's by design. The order of returned records is defined by the ORDER BY clause of SELECT query.
Pavel
Sonork 100.15206
|
|
|
|
|
Can someone give me a practical example/reason of why classes can contain static member functions, aside from data encapsulation I'm not sure I see their purpose. We were talking about them today in a class that I have and my professor couldn't give me any specific reason as to why we have this. Any ideas would be great as I am just a little curious (aside from those that say "So you can call method X without object instantiation" ). Thanks.
Nick Parker
|
|
|
|