|
Now why didn't I think of that; good answer.
Unrequited desire is character building. OriginalGriff
I'm sitting here giving you a standing ovation - Len Goodman
|
|
|
|
|
On reflection I decided to test this and it does not work without any windows, as there is nothing to process the WM_TIMER message, which is used by the default handler to invoke the callback routine.
Unrequited desire is character building. OriginalGriff
I'm sitting here giving you a standing ovation - Len Goodman
|
|
|
|
|
I would be interested to see your test code. I have no problems using a timer callback procedure.
Independent ACN Business Owner- Check out the possibilities for your future!
- Financial independance
- Full time or Part time
- In more than 20 countries through North America, Europe, Asia and the Pacific
- Featuring the ACN IRIS 5000 video phone. See the person you are talking to.
Within you lies the power for good - Use it!
|
|
|
|
|
Looking at it further, the app does not need a window, but if there is no window then the thread needs a message loop.
Independent ACN Business Owner- Check out the possibilities for your future!
- Financial independance
- Full time or Part time
- In more than 20 countries through North America, Europe, Asia and the Pacific
- Featuring the ACN IRIS 5000 video phone. See the person you are talking to.
Within you lies the power for good - Use it!
|
|
|
|
|
PJ Arends wrote: the thread needs a message loop.
That's the issue; even with a callback the timer signals by posting a WM_TIMER message.
Unrequited desire is character building. OriginalGriff
I'm sitting here giving you a standing ovation - Len Goodman
|
|
|
|
|
I have a few apps like that (mostly system services) so at the end of "main()" (or whatever you use), stick code like this:
static MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return(msg.wParam);
It doesn't hurt to sit in this loop while the other threads do their job and it allows them to post WM_CLOSE messages to run-down the process if necessary. Other standard messaging things works, including timers.
|
|
|
|
|
Thanks for the reply,
can you give me more details how to use it?
How can I know which message I Received by msg?
|
|
|
|
|
This is the standard windows message pump, it only causes windows messages to get processed for apps that are not "dialog based". You don't modify this code in any way nor look at the message in that loop. The "dispatch" is done by windows to the proper messsage handler. If you have dialogs, windows does this for you.
|
|
|
|
|
Can you give me exmple how to write a messsage handler ,
I did it only with the class wizard of mfc,
and this is the first time I need to add a timer
to a class that don't connected to any window,
even if I creat a fictive window like dialog box the SetTimer(...)
works only if the dialog is opened by DoModal.
thanks
|
|
|
|
|
I see all kinds of articles and documents on tokens using strtok_s, but none of them show how to get or capture the actual value of a token.
It looks like a token is a pointer, to a place in a char array. but it doesn't seem to give you the length. In the autos, it looks like an array of chars, but I know better now.
char *szServerName[50] = {""};
szServerName = token2;
would be invalid,
I figured out how to step through the source char array in a name value pair
eg. ServerName, DELL760
token1 = ServerName
token2 = DELL760
but I can't figure out how to capture the values. Plus you can't run token1 in a switch, because there is nothing to compare to.
void CA_SQLServer_Scan::_process_SQL_BufferData( std::vector<char> pData, int pLength )
{
int msgLength = pData.size();
char *szWords = new char[msgLength+1];
for (int i = 0; i < msgLength; i++) {
szWords[i] = pData[i];
}
szWords[ pData.size() ] = '\0';
char seps[] = ";";
char *token1, *next_token1, *token2, *next_token2;
char *szServerName[50] = {""};
char *szInstanceName[50] = {""};
char *szClustered[5] = {""};
char *szVersion[25] = {""};
char *szTCP[5] = {""};
char *szNP[80] = {""};
if ( strcmp( szWords, "ServerName" ) !=0 &&
strcmp( szWords, "InstanceName" ) !=0 &&
strcmp( szWords, "Version" ) !=0)
{
token1 = strtok_s( szWords, seps, &next_token1);
token2 = strtok_s( next_token1, seps, &next_token1);
while (token1 != NULL || token2 !=NULL)
{
if ( token1 !=NULL || token2 !=NULL )
{
token1 = strtok_s( next_token1, seps, &next_token2);
token2 = strtok_s( next_token2, seps, &next_token1);
}
}
}
delete [] szWords;
}
|
|
|
|
|
|
That won't work either since szServerName is defined as an array of pointers.
Unrequited desire is character building. OriginalGriff
I'm sitting here giving you a standing ovation - Len Goodman
|
|
|
|
|
char *szServerName[50] = {""};
szServerName = token2;
would be invalid,
Surely it's invalid. You just need to use strcpy() to copy the value from the token. And compare it with the required value.
|
|
|
|
|
|
I think there is quite a lot you don't understand unfortunately; this is a bit of a mess.
You need to understand the difference between a char* and a char* [] . You are also using a vector in your function when you are just passing a null-terminated string. Given your array of SQL information you know that it is in pairs of strings <keyword>;<value> so you just need to split the string into it's constituent parts and process each keyword as required. Something like:
void CA_SQLServer_Scan::_process_SQL_BufferData(char* pszData)
{
char *token1, *nextToken, *token2;
char seps[] = ";";
char *szServerName = NULL;
char *szInstanceName = NULL;
char *szVersion = NULL;
token1 = strtok_s(pszData, seps, &nextToken);
do {
token2 = strtok_s(NULL, seps, &nextToken);
if (strcmp(token1, "ServerName") == 0)
szServerName = token2;
else if (strcmp(token1, "InstanceName") == 0)
szInstanceName = token2;
else if (strcmp(token1, "Version") == 0)
szVersion = token2;
if (token2 == NULL)
break;
token1 = strtok_s(NULL, seps, &nextToken);
} while (TRUE);
Unrequited desire is character building. OriginalGriff
I'm sitting here giving you a standing ovation - Len Goodman
|
|
|
|
|
I had my bubble burst last night by another comment on my experimental code.
I tried if token1 == "ServerName", but it always came out false. Didn't think to use strcmp on the value. I tried to do a switch to, Switch (token1) but it wasn't valid.
Well like I said, I'm only 4 weeks into this. I think once I get a clear understanding of working with data in c++, everyone will see better cleaner code from me.
There alot of people from this technology company pushing me toward using vectors for everything, but I do really need to understand the char first.
Thanks in advance, let me soak it in for an hour.
|
|
|
|
|
jkirkerx wrote: I had my bubble burst last night
Sorry to have to do it again, but I am finding it difficult to understand why you are working on this project when your knowledge of C/C++ is at the level it is. You seem to be struggling with some very basic concepts, which are vital to get your program to work. I would agree that using vectors (and other STL classes) would be a good thing but you really need to have a good grasp of the basics first.
Unrequited desire is character building. OriginalGriff
I'm sitting here giving you a standing ovation - Len Goodman
|
|
|
|
|
I will private message you the reason why, if possible, I'm not that familiar with cp capabilities.
I want to stay within the parameters of the discussion rules.
|
|
|
|
|
Just click on the Email link at the bottom of this message.
Unrequited desire is character building. OriginalGriff
I'm sitting here giving you a standing ovation - Len Goodman
|
|
|
|
|
I have SDI application and two panes. I would like bottom pane to have fixed size (instead of top pane having it). When user moves splitting line bottom pane should maintain newly fixed size. When window is resized, so that there is no room for top pane, bottom pane should occupy whole area. When window is enlarged again bottom pane should occupy last fixed size (ie. enlarge to a certain point and then stay fixed). Standard CSplitterWnd does not have this functionality, and last pane is always expanded to the end, and all previous panes are fixed. I was searching here for appropriate splitter class, but no luck so far. Maybe I'm missing something obvious. Is there a ready made solution? How should I solve this problem?
|
|
|
|
|
|
In linked article there is no mention of fixing the size of particular pane. The only advantage of featured class is that it works on CDialog, and that it uses registry. I've checked all other splitting classes, but either required functionality does not exist, or I can't find it. Hence the original question.
|
|
|
|
|
handle the WM_SIZE message in the parent class (parent of splitter), then size each splitter panel appropriately.
If your actions inspire others to dream more, learn more, do more and become more, you are a leader." - John Quincy Adams You must accept one of two basic premises: Either we are alone in the universe, or we are not alone in the universe. And either way, the implications are staggering” - Wernher von Braun
|
|
|
|
|
My current solution is a monstrosity of a workaround that includes CMainFrame::OnSize handler, and a class derived from CSplitterWnd that exposes "ideal" sizes (you can set them but can't get them), and reroutes TrackRowSize/TrackColumnSize to CMainFrame so that proper size fiddling can be achieved. I am not proud of it, but it seems to be working for now.
|
|
|
|
|
First read Minimum size splitter
then try:
CSplitterWnd::SetRowInfo (horizontal)
Call this member function to set a new minimum height and ideal height for a row. The row minimum value determines when the row will be too small to be fully displayed.
When the framework displays the splitter window, it lays out the panes in columns and rows according to their ideal dimensions, working from the upper-left to the lower-right corner of the splitter window's client area.
void CMyFrame::OnSize(UINT nType, int cx, int cy)
{
if(::IsWindow(m_wndSplitter.m_hWnd) && ::IsWindow(m_wndSplitter2.m_hWnd))
{
m_wndSplitter.SetRowInfo(0, cy*2/3, 10);
m_wndSplitter.SetRowInfo(1, cy/3, 10);
m_wndSplitter2.SetColumnInfo(0, cx/4, 10);
m_wndSplitter2.SetColumnInfo(1, cx*3/4, 10);
RecalcLayout();
}
}
CSplitterWnd::SetColumnInfo (verticle)
Call this member function to set a new minimum width and ideal width for a column. The column minimum value determines when the column will be too small to be fully displayed.
When the framework displays the splitter window, it lays out the panes in columns and rows according to their ideal dimensions, working from the upper-left to the lower-right corner of the splitter window's client area.
Example
void CChildFrame::OnSize(UINT nType, int cx, int cy)
{
CMDIChildWnd::OnSize(nType, cx, cy);
CRect rect;
GetWindowRect( &rect );
if( m_bSplitterCreated )
{
m_wndSplitter.SetColumnInfo(0, rect.Width()/2, 10);
m_wndSplitter.SetColumnInfo(1, rect.Width()/2, 10);
m_wndSplitter.RecalcLayout();
}
}
CSplitterWnd::RecalcLayout
Call this member function to correctly redisplay the splitter window after you have adjusted row and column sizes with the SetRowInfo and SetColumnInfo member functions. If you change row and column sizes as part of the creation process before the splitter window is visible, it is not necessary to call this member function.
|
|
|
|
|