|
How can I know when a button has the focus?
|
|
|
|
|
ArielR wrote: How can I know when a button has the focus?
WM_SETFOCUS -- Is sent when a window has gained focus.
Override afxvoid CWnd::OnSetFocus( CWnd* ) .
Insert a message map entry likewise...
ON_WM_SETFOCUS() .
|
|
|
|
|
Ok, I discovered CButton::GetState(). If return 0x0008 is on Focus. Thanks
|
|
|
|
|
Actually if return & 0x0008 is non-zero then it has the focus.
It's slightly different...
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
|
|
|
|
|
Hi,
I've encountered a problem where windows preempts for 16ms on a very simple code i'm running.
In order to check it out I've written a simple code :
while (1)
{
int t = timeGetTime();
Sleep(1);
printf ("%d,",timeGetTime()-t);
}
the result i got where interesting - on some machines i got 1-2ms and on others 16ms.
all machines run XP with no processes running in the background.
I've tried running the same process in real-time and in normal mode - the results where the same.
|
|
|
|
|
Read this[^] and this[^].
"It's supposed to be hard, otherwise anybody could do it!" - selfquote "High speed never compensates for wrong direction!" - unknown
|
|
|
|
|
Thanks,
I know that windows is not a real-time OS.
I would expect the behavior to be inconsistent, depending on many variables.
but in this case on the behavior is consistent on some machines 1-2ms and on the others 16ms.
|
|
|
|
|
Nir sheffi wrote: but in this case on the behavior is consistent on some machines 1-2ms and on the others 16ms
hence it is inconsistent.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
|
|
|
|
|
yes,
but consistent on the same machines
|
|
|
|
|
Nir sheffi wrote: I would expect the behavior to be inconsistent.......but in this case on the behavior is consistent on some machines 1-2ms and on the others 16ms.
Ok, so what is your question?
The articles I linked to in my previous post gives you multiple reasons to why you won't get the control back within 1 ms if you call ::Sleep( 1 ) . If you want to pinpoint exactly the reason why this is happening on the machines you've tested, I cannot help you with that for two reasons:
1. It would be a tedious job to track the reason down and it would presumably require investigation of the machines and how they are set up.
2. When the reason is found we cannot do anything about it. There's no way to change the behaviour since this is how the system works. It would simply be a waste of time.
My approach is more pragmatic...
It doesn't matter what the exact reason is in this case. On another machine it would be another reason. The fact is that ::Sleep() gives unpredictable results and if time is of the essence you should find an alternative solution, such as multimedia timers which would give the best resolution on a windows OS.
Don't spend time tracking the exact reason down because you cannot use that information for anything. It can be interesting from a technical point of view, but then you're on your own.
"It's supposed to be hard, otherwise anybody could do it!" - selfquote "High speed never compensates for wrong direction!" - unknown
|
|
|
|
|
Nir sheffi wrote: Hi,
I've encountered a problem where windows preempts for 16ms on a very simple code i'm running.
Hi there, you may be able to improve your timer performance by doing the following:
<br />
void SetResolution(UINT milliseconds)<br />
{<br />
TIMECAPS tc;<br />
if (TIMERR_NOERROR == timeGetDevCaps(&tc, sizeof(tc)))<br />
{<br />
static UINT wTimerRes = min(max(tc.wPeriodMin, milliseconds), tc.wPeriodMax);<br />
timeBeginPeriod(wTimerRes);<br />
m_resolution = wTimerRes;<br />
}<br />
}<br />
In addition you will get better accuracy by utilizing multi-media timers.
UINT m_timerID = timeSetEvent(m_eventDelay, m_resolution, OnTimer, (DWORD_PTR)this, TIME_PERIODIC);<br />
|
|
|
|
|
For clarity reasons:
The timeXXXX functions all apply to the multimedia timers.
Calling ::timeBeginPeriod() will not change how ::Sleep() works.
"It's supposed to be hard, otherwise anybody could do it!" - selfquote "High speed never compensates for wrong direction!" - unknown
|
|
|
|
|
Hi Roger,
According to the MSDN the timeBeginPeriod API call affects the Sleep() quantum and all timers associated with the application.
http://msdn2.microsoft.com/en-us/library/ms686298.aspx[^]
However, in my experience timeBeginPeriod with standard Sleep() did not have as much of an effect!
The author of the question will certainly get best performance by utilizing multi-media timers.
Best Regards,
David Delaune
|
|
|
|
|
Hi David,
Randor wrote: According to the MSDN the timeBeginPeriod API call affects the Sleep() quantum and all timers associated with the application.
Yes, I saw that in the link you provided.
However, I think it's wrong, or at least misguiding. The section about timeBeginPeriod() has been added at much later date. It doesn't exist in my MSDN release from July 2001, nor does the documentation about ::timeBeginPeriod() mention this. The fact that the ::timeXXXX() functions are part of the multimedia timer library winmm.lib and ::Sleep() is not, also implies to me that the current MSDN documentation is erroneous.
Even if the MSDN documentation is correct and calling ::timeBeginPeriod() would change the resolution of ::Sleep() , there would be no point in doing it because of the way ::Sleep() works. The calling thread enter a busy wait state and if the thread is preempted it probably won't run until a time ridiculously greater than the resolution set with ::timeBeginPeriod() .
Randor wrote: The author of the question will certainly get best performance by utilizing multi-media timers.
Absolutely.
"It's supposed to be hard, otherwise anybody could do it!" - selfquote "High speed never compensates for wrong direction!" - unknown
|
|
|
|
|
Hi Roger,
Roger Stoltz wrote: The calling thread enter a busy wait state and if the thread is preempted it probably won't run until a time ridiculously greater than the resolution set with ::timeBeginPeriod().
Are you actually implying that several milliseconds pass between thread preemtions? This is incorrect.
I do some kernel driver development so perhaps I have a unique view of this; let me explain.
The maximum measureable time increment is stored in a link list at the kernel level. As you may be aware the kernel keeps track of all processes in an EPROCESS structure. The kernel also has available a struct associated with processes: PROCESS_INFORMATION_CLASS. The behavior and capabilities of each process can be accessed using NtQueryInformation and passing a valid buffer with sufficient size.
If you take a look at the struct SYSTEM_BASIC_INFORMATION:
typedef struct _SYSTEM_BASIC_INFORMATION<br />
{<br />
DWORD d00;
DWORD dKeMaximumIncrement;
DWORD dPageSize;
DWORD dMmNumberOfPhysicalPages;<br />
DWORD dMmLowestPhysicalPage;<br />
DWORD dMmHighestPhysicalPage;<br />
DWORD dAllocationGranularity;
PVOID pLowestUserAddress;<br />
PVOID pMmHighestUserAddress;<br />
DWORD dKeActiveProcessors;<br />
BYTE bKeNumberProcessors;<br />
BYTE bReserved01;<br />
WORD wReserved02;<br />
}<br />
SYSTEM_BASIC_INFORMATION,<br />
* PSYSTEM_BASIC_INFORMATION,<br />
**PPSYSTEM_BASIC_INFORMATION;<br />
<br />
#define SYSTEM_BASIC_INFORMATION_ \<br />
sizeof (SYSTEM_BASIC_INFORMATION)<br />
Using the DWORD value dKeMaximumIncrement you can determine the default "timer resolution" for any system.
<br />
SYSTEM_BASIC_INFORMATION sbi;<br />
...<br />
_stprintf((T("Maximum time resolution: %lu (%lu Hz)"), (TICKS_PER_SECOND / sbi.dKeMaximumIncrement) + (TICKS_PER_SECOND % sbi.dKeMaximumIncrement >= sbi.dKeMaximumIncrement >> 1 ? 1 : 0));<br />
The results on my system:
Maximum time resolution: 156250 (64 Hz)
So lets see what this means.
1 second contains 1000 milliseconds. (1000 / 64) == 15.625 milliseconds.
So what this means is if I do a Sleep(1) it will actually sleep about 15.625 milliseconds.
What I am saying is, the timeBeginPeriod() function is modifying the timer resolution at the kernel level which is associated with the process. This will affect all timers. The reason why MM timers function so much better is because they are actually callbacks. A standard WM_TIMER message will still be slowed by the MFC message loop.
Hopefully we all understand timers a bit better. If not I can go into greater detail.
Best regards,
-David Delaune
|
|
|
|
|
Hello again David
Randor wrote: Roger Stoltz wrote: The calling thread enter a busy wait state and if the thread is preempted it probably won't run until a time ridiculously greater than the resolution set with ::timeBeginPeriod().
Are you actually implying that several milliseconds pass between thread preemtions? This is incorrect.
No, that's not what I'm implying and if I did it would be incorrect.
What I meant was that ::Sleep() doesn't return unless the thread that called it is running. If the thread is preempted it won't run until it's given another timeslice which is approx. 10 msec under normal circumstances. This will happen if another thread is scheduled to run regardless of how ::timeBeginPeriod() works and what it affects. The resolution of the timer doesn't matter in this case.
If a developer desires to have a resolution close to 1 msec and in fact he gets a delay that exceeds 10 msec if the thread is preempted, I would consider it ridiculously greater than 1 msec.
If you still don't understand what I'm getting at, please read this[^] and this[^].
Slightly off topic:
To my knowledge the implementation of ::Sleep() is a "busy-wait" which means that it's continuously reading the time asking "are we there yet" until the desired time has passed.
This may have changed, but I still treat it as if it still is implemented as a busy-wait. It doesn't matter since I avoid calling ::Sleep() .
Regarding the WM_TIMER message it's even worse: it won't even make it to the message queue. The WM_TIMER message is a low priority pseudo message that will be handled when all other pending messages have been handled. This means that even if the timer set with SetTimer() has expired multiple times before being handled, the message handler for the timer message will only be called once.
--
Roger
"It's supposed to be hard, otherwise anybody could do it!" - selfquote "High speed never compensates for wrong direction!" - unknown
|
|
|
|
|
Hey guys,
There is a great addin here on Code Project:
AutoBuild[^]
But, the article has no directions on how to "install" the .dll addin, and I would like to use it with VS 2005.
Thanks for any help.
Patrick
|
|
|
|
|
Stick^ wrote: But, the article has no directions on how to "install" the .dll addin, and I would like to use it with VS 2005.
Thanks for any help.
Does this help?
"A good athlete is the result of a good and worthy opponent." - David Crow
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
Hi All
I have the below bit of code, it seems that some users somehow are getting the below statement to return TRUE when m_message > 160
can anyone see any problems with this ?
thanks
Simon
int nBytes = lstrlen(m_message);
if (nBytes >160)
{
AfxMessageBox("You have exceeded the maximum number of\ncharacters allowed", MB_ICONSTOP);
return FALSE;
}
else
return TRUE;
|
|
|
|
|
I am not seeing where that would be possible, other than the possibility that m_message is a character buffer (not a string, right?), and there is some other overrun/underrun that is stepping on that buffer...? Or stuffing UNICODE data into a char buffer?
Peace!
-=- James Please rate this message - let me know if I helped or not!<HR> If you think it costs a lot to do it right, just wait until you find out how much it costs to do it wrong! Avoid driving a vehicle taller than you and remember that Professional Driver on Closed Course does not mean your Dumb Ass on a Public Road! See DeleteFXPFiles
|
|
|
|
|
sorry should have put that m_message is CString
|
|
|
|
|
If it is a CString , use m_message.GetLength() instead - generally, if an object has a method for some function, you should use it because it may be optimized for that particular object.
Mismanagement of the CString object can also lead to corruption of its data - for example, if you have a reference to that CString someplace that is getting messed around with.
You can also ovverun/underrun heap memory (which the string object uses) by not being too careful with them. If you have any code that casts a CString object into a non-const pointer, that is a good place to start.
Peace!
-=- James Please rate this message - let me know if I helped or not!<HR> If you think it costs a lot to do it right, just wait until you find out how much it costs to do it wrong! Avoid driving a vehicle taller than you and remember that Professional Driver on Closed Course does not mean your Dumb Ass on a Public Road! See DeleteFXPFiles
|
|
|
|
|
si_69 wrote: m_message is CString
In that case instead of lstrlen, use m_message.GetLength();
nave
|
|
|
|
|
Hi all:
I need to write a function whose signature is:
std::string readWord(ifstream& in);
The function will read one word at a time from "in", and the definition of word is a sequence of alphabetic, apostrophe, hyphen or underscore characters. Anything else is treated as a "white space".
My approach is:
Use fgetc() to read one character at a time from "in", then test it to see if it is a valid character; this procedure will be repeated until the function reads all the characters between two "white spaces".
Any comments is welcome.
Thank you
|
|
|
|
|
an ifstream will only read up to a space anyhow, I would have thought that
string s;
in << s;
return s;
would do it. What you're saying will also work
Christian Graus - Microsoft MVP - C++
Metal Musings - Rex and my new metal blog
"I am working on a project that will convert a FORTRAN code to corresponding C++ code.I am not aware of FORTRAN syntax" ( spotted in the C++/CLI forum )
|
|
|
|