|
|
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.
|
|
|
|
|
Thank you for MSDN reference, but my goal has nothing to do with splitter's minimum size. The ideal solution would be the one that has different RecalcLayout algorithm that recalculates layout the way I want it, having in mind what panes have fixed size (until user changes it), and what panes should be resized when the window is resized. Currently only the last pane is resized (the rightmost, or the "bottomest"), and all previous are fixed. Along with RecalcLayout rewrite there should be an update in TrackRowSize/TrackColumnSize so that fixed panes remain fixed (unless the user is resizing one just now), and resizable panes get resized to compensate for current pane reconfiguration.
|
|
|
|
|
I wonder if what you want to use is CDockablePane .
The MFC "Visual Studio" Project style (available in VS2010) demonstrates usage of the CDockablePane and has the behavior you're describing.
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
|
|
|
|
|
Funny this. I created project from VS template and tested it a bit. If you shrink the window to a minimum then left and right dockable panes will also shrink and will not grow back. Then I tried the same thing with Visual Studio itself and the same thing happens. Dockable panes shrink, but do not grow back. But at least we have middle area that takes all the non-fixed space.
If those dockable panes could be prevented from undocking, hiding, auto-hiding, and if they could be made without titlebars, so that they resemble another client area, then I would have something close to original idea. But without the panes growing back when there's available space.
|
|
|
|
|
how to add the help file in an SDI Application i tried with this
::HtmlHelp(this->m_hWnd,_T(" WordRecovery.chm"),HH_DISPLAY_TOPIC,NULL);
|
|
|
|
|
sarfaraznawaz wrote: i tried with this
And what exactly happened?
[edit]
This article[^] may be of interest.
[/edit]
Unrequited desire is character building. OriginalGriff
I'm sitting here giving you a standing ovation - Len Goodman
|
|
|
|
|
MSDN says:
The following example calls the HH_DISPLAY_TOPIC command
to open the help file named Help.chm and display
its default topic in the help window named Mainwin .
Generally, the help window specified in this command is a standard HTML Help Viewer.
MSDN Example
HWND hwnd =
HtmlHelp(
GetDesktopWindow(),
"c:\\Help.chm::/Intro.htm>Mainwin",
HH_DISPLAY_TOPIC,
NULL) ;
|
|
|
|
|
hi i have use the GetCurrentDirectory now i want to change the Directory with SetCurrentDirectory can any one explain with Example
thanks
SARFARAZ
|
|
|
|
|
Well, the MSDN can, as always: SetCurrentDirectory[^]
If after reading the article something is still unclear, please post a detailed description (with source code showing what you have tried). It's hard to target a specific problem with a general question...
|
|
|
|
|
#include <windows.h>
#include <stdio.h>
#define BUFFER_SIZE 200
int main()
{
TCHAR infoBuf[BUFFER_SIZE];
TCHAR lpPathName[200] = "c:\\";
if(!GetCurrentDirectory(BUFFER_SIZE, infoBuf)) printf("GetCurrentDirectory() failed!\n");
printf("Your current directory is: %s\n", infoBuf); printf("Changing directory...\n");
if(!SetCurrentDirectory(lpPathName)) printf("SetCurrentDirectory() failed!\n");
if(!GetCurrentDirectory(BUFFER_SIZE, infoBuf)) printf("GetCurrentDirectory() failed!\n");
printf("Your current directory is: %s\n", infoBuf);
if(!GetWindowsDirectory(infoBuf, BUFFER_SIZE)) printf("GetWindowsDirectory() failed!\n");
printf("Your Windows directory is: %s\n", infoBuf);
if(!GetSystemDirectory(infoBuf, BUFFER_SIZE)) printf("GetSystemDirectory() failed!\n");
printf("Your system directory is: %s\n", infoBuf);
return 0;
}
|
|
|
|
|
I understand now that the data I receive from a socket is a byte array.
But I don't understand how to pass the byte array to a function for further processing. Plus I'm not sure if I should leave it as a byte array, or try to convert it to a string, so I can extract data from it. I'm confused as to whether this buffer is a pointer to data somewhere else, and If I need to make a copy of it, before passing it to a function. When I pass it to a function, the data is lost.
Kind of tired of going around in circles here on this, and I need road map to head in the right direction.
I make my receive buffer
char recvbuf[256];
I get data
0x05 '' 0x54 'T' 0x53 'S' 0x65 'e'
And I try to pass it to a function for processing. Unless just extracting the info I need does not require a function. Suggestion?
void _process(char *pbuffer)
{
}
|
|
|
|
|
I can't speak for your application nor what data you will be receiving from the socket. But if the data is a "protocol", that is, some well defined sequence of bytes with fields, flags, data, etc, then it is most likely that the information is "binary", that is, not all the data maps nicely into printable or viewable characters, all zero bytes comes to mind, your 0x05 example too.
C and C++ "string" variables, whether CString or std::string and their manipulation functions are not really tolerant of nulls intersperced in the data.
C# strings do allow nulls in the data and I have seen many a C / C++ programmer get totally confused by the idea of nulls in strings.
So, I'd say save yourself some future grief and use a byte array. Passing a byte array is no different than passing a char array other than some folks incorrectly equate "char array" with "string" in all cases.
|
|
|
|
|
Great Information!
In this case, the data being received are byte stream?
Header stuff, ServerName:WWW;Custered:false;NamedPipe:\\pipename;Version:1.5.02.23;empty space
Taking into consideration the thread below yours, I will make a copy of the buffer, and pass the copy to the function to fish out the server name, and version.
Thanks for looking at my post, your advice puts back on track.
jkirkerx
|
|
|
|
|
Don't convert it to a string... that's a bad idea... extract whatever data bytes according to whatever API you happen to be using, then cast the converted bytes to whatever type they're supposed to be. As far as whether you need to copy the data before passing it, it depends on where you defined your recvbuff[] and whether it'll be used again, if the buffer is a local variable within your receive method, then it'll automatically go out of scope when the method is finished, so you should copy the data... also, if the buffer is to be used repeatedly (receiving multiple packets), then the data should be copied over to another buffer before moving on, otherwise it might be overwritten before it's used downstream.
|
|
|
|
|
The research I did made it sound like std:string was the swiss army knife or manipulation.
I used memset to copy the data, because I could not figure out how to use strcpy, the copy has the first 2 bytes, and stopped.
I still can't figure out why when I pass the data, I only get the first 2 bytes.
You wisdom gives me a map to use, so I can focus on the copy and pass, then I have to tackle the data extraction.
Thank you very much
jkirkerx
|
|
|
|
|
You seem to be working at this from the wrong direction. The first thing you need to do is work out (or ask the sender) the exact format of the data you are receiving. All data read from sockets is presented as a stream of bytes, and without knowing the significance, format and values of each byte or group of bytes, there is no way you can do anything with the information you receive. Never assume that data is presented as a string unless you are certain that is how it has been sent.
|
|
|
|
|
The sender is microsoft's sql browser. I discovered the return packet data using etherreal, and sending various request to it, until I got the reply I was looking for. Then I wrote the socket program. I have the data packets coming back from all the sql servers on the lan, and they all send the same format back to me. I just need to extract the server name and version number of sql out of the byte array.
|
|
|
|
|
jkirkerx wrote: I just need to extract the server name and version number of sql out of the byte array.
Given that you have figured out the format and content of the messages, what is the problem?
|
|
|
|
|
Yeah, if you know the data is a char array, pass it to the func as you outineline in your post, and let it do the processing.
It is bette to do this, than to proces the data at the level of the code that manages socket communication, it is a more logical split to treat communication at one level, and data processing at another.
==============================
Nothing to say.
|
|
|
|
|
I write in vb, and without a doubt, I would pass the data to another function for processing, or just store the data, and process it later. In straight c++, most of the stuff seems pretty easy, but there are some really low level stuff you can get into that gets tricky.
I've never asked anyone to write code for me, but I'm really stuck trying to figure out how to pass the data to a another function. I will post my code, and the byte stream I get back, and perhaps someone could can spot the mistake I made, it might be something really small that I didn't get.
BOOL CA_SQLServer_Scan::_socket_Enumerate_SQLServers( void )
{
int iResult;
WSADATA wsaData;
char recvbuf[256];
int rv = 0;
int recvbuflen = 256;
int bytesReceived = 0;
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != NO_ERROR) {
return FALSE;
}
SOCKET sUDPSocket = INVALID_SOCKET;
struct sockaddr_in sTargetDevice;
char cBuffer[] = {0x02};
sUDPSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (sUDPSocket == INVALID_SOCKET) {
int iSocketError = WSAGetLastError();
goto wsaCleanup;
}
ZeroMemory( &sTargetDevice, sizeof(sTargetDevice));
sTargetDevice.sin_family = AF_INET;
sTargetDevice.sin_addr.s_addr = inet_addr( "192.168.3.255" );
sTargetDevice.sin_port = htons( BROADCAST_SND_PORT );
iResult = sendto(sUDPSocket, cBuffer, 1, 0, (SOCKADDR *) & sTargetDevice, sizeof (sTargetDevice));
if (iResult == SOCKET_ERROR) {
goto closeSocket;
}
iResult = shutdown(sUDPSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
goto closeSocket;
}
do {
bytesReceived = recv(sUDPSocket, recvbuf, recvbuflen, 0);
if ( bytesReceived > 0 ) {
char buf[256];
recvbuf[bytesReceived] = '\0';
memcpy(buf, recvbuf, bytesReceived);
_process_SQL_BufferData(buf, bytesReceived);
}
else if ( bytesReceived == 0 ) {
printf("Connection closed\n");
goto closeSocket;
}
else {
printf("recv failed: %d\n", WSAGetLastError());
goto closeSocket;
}
}
while( bytesReceived > 0 );
closeSocket:
iResult = closesocket(sUDPSocket);
if (iResult == SOCKET_ERROR) {
goto wsaCleanup;
}
wsaCleanup:
WSACleanup();
return TRUE;
}
void CA_SQLServer_Scan::_process_SQL_BufferData( char pBuffer[256], int packetSize )
{
}
The first data packet returned from the request, I put the \0 at the end in 87, perhaps not needed.
Bytestream - first 87 bytes of recvbuf.
recvbuf 0x0012f8a0 "T" char [256]
[0] 5 '' char
[1] 84 'T' char
[2] 0 char
[3] 83 'S' char
[4] 101 'e' char
[5] 114 'r' char
[6] 118 'v' char
[7] 101 'e' char
[8] 114 'r' char
[9] 78 'N' char
[10] 97 'a' char
[11] 109 'm' char
[12] 101 'e' char
[13] 59 ';' char
[14] 68 'D' char
[15] 69 'E' char
[16] 76 'L' char
[17] 76 'L' char
[18] 67 'C' char
[19] 53 '5' char
[20] 50 '2' char
[21] 49 '1' char
[22] 45 '-' char
[23] 48 '0' char
[24] 49 '1' char
[25] 59 ';' char
[26] 73 'I' char
[27] 110 'n' char
[28] 115 's' char
[29] 116 't' char
[30] 97 'a' char
[31] 110 'n' char
[32] 99 'c' char
[33] 101 'e' char
[34] 78 'N' char
[35] 97 'a' char
[36] 109 'm' char
[37] 101 'e' char
[38] 59 ';' char
[39] 83 'S' char
[40] 81 'Q' char
[41] 76 'L' char
[42] 69 'E' char
[43] 88 'X' char
[44] 80 'P' char
[45] 82 'R' char
[46] 69 'E' char
[47] 83 'S' char
[48] 83 'S' char
[49] 59 ';' char
[50] 73 'I' char
[51] 115 's' char
[52] 67 'C' char
[53] 108 'l' char
[54] 117 'u' char
[55] 115 's' char
[56] 116 't' char
[57] 101 'e' char
[58] 114 'r' char
[59] 101 'e' char
[60] 100 'd' char
[61] 59 ';' char
[62] 78 'N' char
[63] 111 'o' char
[64] 59 ';' char
[65] 86 'V' char
[66] 101 'e' char
[67] 114 'r' char
[68] 115 's' char
[69] 105 'i' char
[70] 111 'o' char
[71] 110 'n' char
[72] 59 ';' char
[73] 49 '1' char
[74] 48 '0' char
[75] 46 '.' char
[76] 53 '5' char
[77] 48 '0' char
[78] 46 '.' char
[79] 49 '1' char
[80] 54 '6' char
[81] 48 '0' char
[82] 48 '0' char
[83] 46 '.' char
[84] 49 '1' char
[85] 59 ';' char
[86] 59 ';' char
[87] 0 char
|
|
|
|
|
Does this code help point you in the right direction?
rcvBuffer is passed to the function processData
#include <iostream>
#include <vector>
void processData(char &c)
{
char* array = &c;
std::cout << array << std::endl;
}
int main()
{
char* rcvBuffer = "Hello world";
char& c = rcvBuffer[0];
processData(c);
return 0;
}
|
|
|
|
|