|
Actually I was hoping that I could avoid using a HWND which is needed for the timers (that I know of). I would prefer if my network module could be seperated from the UI part.
|
|
|
|
|
HWND required for timers?
What is your target platform? If you are targeting Windows 98 or later, then look into CreateWaitableTimer. I can't help but be amused at the number of solutions that go out of their way to make a window of some sort just because they think SetTimer is the only way to get a timeout message in an application
|
|
|
|
|
The ideal situation would be if could (without relying on windows) do the following:
thread T1 {
loop {
wait for (received datagram OR
update table event OR
send broadcast event) {
}
}
}
Using only one thread would allow me to avoid headaches from dealing with concurrent use of the same datastructure used by both the "receive datagram" and "update table". Is this doable?
|
|
|
|
|
If you can 1) get the UDP events without blocking on the receive, 2) send UDP packets without blocking, and 3) use CreateWaitableTimer, then I think this would be possible. If you are constantly getting receive events, then you will also need to maintain an internal record of when you most recently checked the table, so that you can also automatically check it every 2 seconds even if the CreateWaitableTimer has not expired, or if you miss its event because your thread was busy servicing many receive events.
In other words, you need the 2 second timer in case there is no activity, but you also need to know when 2 seconds have gone by in case you are busy otherwise - you still need to check your table periodically. If you don't need high precision on that 2 seconds, then you can use some GetTickCount() math to track elapsed time.
|
|
|
|
|
I've been trying to find a way to wait for multiple events, both timer and network events at the same time. It looks like I would need a function that does the job as WaitForMultipleObjects and WSAWaitForMultipleEvents at the same time. Or is it possible to use the WSAEVENTs with WaitForMultipleObjects?
I'm not 100% sure that I understood the bit about missing events. If I've understood it correctly events are signaled via flags and you can wait for these flags to be signaled via, for example, WaitForMultipleObjects.
If the timer expires it should set its flag and if I do:
loop {
e = select_event_from_all_signaled_events()
}
I would eventually see that the timer event was signaled (I might catch it later than I intended but it shouldn't be lost). I only need to receive timer events every 15 seconds or so and precision is not important (if it differed by 2 second it would still be no problem).
|
|
|
|
|
I am not sure if the WSA events can be used in the WaitForMultipleObjects.
The reference to 'missing' timing events could have occurred if your thread was so busy processing network events that it did not 'time out' right at 2 seconds, but rather saw the timer event some time AFTER it had finished processing network events. However, since your processing of 'timers' is not so critical, that part would probably work fine.
|
|
|
|
|
It was as I thought then. I expect for the program to be waiting most of the time and receive an UDP message every 30 seconds or so and send one every 60 seconds or so.
I'm suspecting that it isn't possible to construct and entirely event passed (passive) solution for this problem. If I can't find some callback mecanism for both the network and timing events that is.
|
|
|
|
|
Given this situation, I would be inclined to create two threads. One that waits on the WSA Events and the second one running the timer and waiting on regular events. You can always communicate between the two threads when you receive a UDP packet so the timer thread does not improperly update information for a UDP packet you already processed.
For example, the WSA thread would communicate with the timer thread. If the timer thread times out and then scans the packet information, it can skip the processing for UDP data recently observed. Also, the WSA thread could set 'regular' events that can trigger activity in the timer thread. It seems more problematic to go in the other direction. If you use MsgWaitForMultipleObjects in the timer thread, you can use PostThreadMessage to send messages to the timer thread from the WSA thread.
|
|
|
|
|
I have a toolbar on SDI frame. I am able to add the buttons onto the toolbar at run time. I want to draw line or draw rect on that buttons. I don't want to insert a BMP into it.Can anybody let me know how I can draw line or draw rect on that buttons at run time. Thank you in advance!!!
|
|
|
|
|
All projects in VC6 seem to have MBCS defined by default.
With MBCS, a logical character can be 1 byte or 2 bytes.
therefore it is very important that we do not use _TCHAR *p; p++
but use _tcsinc(p).
But in most of the projects I have seen, I have not seen anyone using
_tcsinc anywhere. now dont say you dont use p++ either, its little hard to believe.
So how many of you use _tcsinc? If you dont, do you think it is not necessary? is it because your program will never run into multibyte character strings?
a google search on "_tcsinc" yielded only 356 results!
pliss to clarify. Thanks.
|
|
|
|
|
it's the first time i ear of _tcsinc() ...
my programs use MBCS and I use TCHAR ... you just have to #define _UNICODE (or not).
i don't really understand what is your problem with TCHAR and what _tcsinc() gives more...
TOXCCT >>> GEII power [toxcct][VisualCalc]
|
|
|
|
|
1. You should read: http://msdn.microsoft.com/archive/default.asp?url=/archive/en-us/dnarvc/html/msdn_mbcssg.asp[^]
2. You either define _MBCS or _UNICODE, but not both.
3. If you define _MBCS, then the above doc tells you why you should use _tcsinc and not p++. with p++, you may end up in the middle of a 2 byte character. So you should use the macro _tcsinc, which increments p by 1 or 2 depending on whether the character at p is a 1 byte char or 2 byte char.
4. My only worry is that this document is 10 years old, so I am not sure any changes have gone into the compiler for automatically using _tcsinc for p++, but that is unlikely(or I dont know, you folks here should tell me that).
back to you guys.
|
|
|
|
|
MSDN is regularly updated, so, even if this article is dated from August 1995, it is still going...
TOXCCT >>> GEII power [toxcct][VisualCalc]
|
|
|
|
|
Flace wrote:
a google search on "_tcsinc" yielded only 356 results!
You should also search for CharNext , the win32 API equivalent of the C runtime function _tcsinc .
"You're obviously a superstar." - Christian Graus about me - 12 Feb '03
"Obviously ??? You're definitely a superstar!!!" mYkel - 21 Jun '04
Within you lies the power for good - Use it! Honoured as one of The Most Helpful Members of 2004
|
|
|
|
|
okay, that gives more results. perhaps it is more known to people than the _tcsinc.
Do you use either of these in your programs?
|
|
|
|
|
I missed an important question in the previous post:
if you dont use _tcsinc, you are either assuming the string have 1 byte characters or your program will go wrong someday. And if you assume your char is 1 byte, then using _TCHAR doesnt make sense. You can use just the char as well. What do you folks say?
|
|
|
|
|
If you use TCHAR, you are IMPLYING your string can be UNICODE if a UNICODE build is made. If your string must ABSOLUTELY be 'single byte characters' then use 'char' and if it must absolutely be UNICODE, then use wchar_t or WCHAR. You can potentially convert back and forth with MultiByteToWideChar and WideCharToMultiByte.
If you want your 'single-byte-character' processing to be internationalized, then at least compile for MBCS and use the 'mbs' for every hard-coded 'char' string and the '_tcs' functions on every TCHAR string. You get BIZARRE results if you hard code to an 'mbs' function against a TCHAR string and then commpile for UNICODE. Now you would be passing a wide-character string to a function expecting multi-byte character string.
Summary:
char -> use str or (preferably) mbs functions
TCHAR -> use tcs functions (compile either way)
WCHAR or wchar_t -> use wcs functions
|
|
|
|
|
Flace wrote:
So how many of you use _tcsinc?
I don't use any of the _tcsxxx() functions. For what I'm working on, there is no need.
Flace wrote:
a google search on "_tcsinc" yielded only 356 results!
What about those folks that do use it but don't publish their code?
"Opinions are neither right nor wrong. I cannot change your opinion. I can, however, change what influences your opinion." - David Crow
|
|
|
|
|
DavidCrow wrote:
What about those folks that do use it but don't publish their code?
You are right, google search doesnt indicate that people do not use it. i was only looking at how people have used it, through google.
|
|
|
|
|
For starters, our codebase is not accessible by Google... :->
There is also CharNext to consider.
There is also _mbsinc to consider.
I agree, however, that the code is more portable to other data formats if the _tcsinc is used instead.
We have a mixcture of ALL of the functions, unfortunately.
Newer (and overhauled) code is using _tcsinc
|
|
|
|
|
|
Flace wrote:
All projects in VC6 seem to have MBCS defined by default.
Always the first thing i change.
I always set to either UNICODE or nothing.
I always explicitly use unicode or ansii string class'/functions.
Not a big fan of this whole 'it may be ansii, it may be unicode, it may be mb'.
...cmk
Save the whales - collect the whole set
|
|
|
|
|
class CEncoderView is a MDI's view class. class CBMWin which derived from class CWnd is the subwindow of class CEncoderView.
I want to save the view as a DIB, so that I firstly DoModal a dialog for getting the DIB file's path. then I send a message MY_SAVEWHOLE which is handled in DefWindowProc to save the view as a DIB file.But I find the dialog is also appeared in the DIB file.
In order to clear the dialog, I invalidate the whole desktop befor saving the view shown as step 1 in the source code below. At this time, there are only the subwindow frames be showed in the DIB. they client rect is empty,because they did't redraw themselves.
In step 2 shown in the source code below, I get messages from the message queue. I want to save the view after all of its subwindows have send a message MY_REDRAW to it. But I find that the function GetMessage can't retrieve message MY_REDRAW at label A in the source code below. Meanwhile, I can retrieve the message MY_REDRAW in the function DefWindowProc at label B which shown in the source code below.
How the message be dispatch in the window?
#define MY_SAVEWHOLE WM_APP + 2 //save a view window as a file
#define MY_REDRAW WM_APP + 3 //have redrawed a subwindow
void CEncoderView::OnExportimage()
{
CExportImageDlg exportidlg( this );
int nRet = -1;
nRet = exportidlg.DoModal();
if (( nRet == -1 ) || ( nRet == IDABORT ))
{
AfxMessageBox( "Dialog box could not be created!");
return;
}
if ( nRet != IDOK )
{
return;
}
//added in step 1
//redraw all windows
::InvalidateRect( NULL, NULL, FALSE );
//end of added in step 1
//added in step 2
//the number of subwindows whose type isCBMWin
int iRedrawedSubWin = 0;
MSG msg;
int bRet;
//if all of the subwindows had redrawed themselves
//then save the view as a DIB
while(( iRedrawedSubWin < iSubWinNum ) &&
((bRet = ::GetMessage( &msg, NULL, 0, 0 )) != 0))
{
//can't retrieve message MY_REDRAW at this point
if ( msg.message == MY_REDRAW )
{
//never execute,can't retrieved message MY_REDRAW
label A: iRedrawedSubWin++;
}
if (bRet == -1)
{
break;// handle the error and possibly exit
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
//end of added in step 2
::SendMessage( m_hWnd, MY_SAVEWHOLE, ( WPARAM )( &exportidlg.m_CSFileRoute ), NULL );
}
LRESULT CEncoderView::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
CBMWin* pChildWnd = NULL;
int iRetValue;
PBITMAPINFO pBitmapInfo = NULL;
switch( message )
{
case MY_SAVEWHOLE:
iRetValue = Win2DIB( this, &pBitmapInfo);
if ( iRetValue != ERR_OK )
{
return 0;
}
SaveDIBFile( pBitmapInfo, ( CString* )wParam );
free( pBitmapInfo );
return 0;
case MY_REDRAW:
//when subwindow redraw,this message can be retrieved
label B: iRetValue = 0; //no mean.
}
return CView::DefWindowProc(message, wParam, lParam);
}
void CBMWin::OnPaint()
{
CPaintDC dc(this); // device context for painting
RECT rect;
GetClientRect( &rect );
//draw a DIB on the client rect
StretchDIBits( dc,
0, 0, rect.right, rect.bottom,
0, 0, ...);
//tell the prarent window CEncoderView it has redrawed itself
::SendMessage( GetParent()->m_hWnd, MY_REDRAW, NULL, NULL );
}
andy
|
|
|
|
|
How to fix (custom ActiveX)control size in design time.
I am using MFC ActiveX ControlWizard.
Please help me.
Thanks
David Park
|
|
|
|
|
Hello,
I am currently trying to change from VB .Net to VC++ .Net.
I am trying to take information from a KeyUp event in the main form (form1), and put the KeyData into label1->Text .
Here is my code:
private: System::Void Form1_KeyUp(System::Object * sender, System::Windows::Forms::KeyEventArgs * e)
{
label1->Text = e->KeyData;
}
However, it returns me the error saying that "c:\...\TestingC++\Form1.h(96): error C2664: 'System::Windows::Forms::Control::set_Text' : cannot convert parameter 1 from 'System::Windows::Forms::Keys' to 'System::String __gc *'"
What should I do to correct this error?
Any help will be greatly appreciated,
Programmer2k4
My sig:
"And it is a professional faux pas to pay someone else to destroy your computer when you are perfectly capable of destroying it yourself." - Roger Wright
I now use my CodeProject Blog!
Most recent blog post: March 24
|
|
|
|