|
thank you, that is a reasonable explanation
|
|
|
|
|
Hi!
I just created a control with the dialog designer in Visual Studio (added dialog resource and set the Control property to true - adds DS_CONTROL flag). How do I make this control part of a window that I create with CreateWindow()?
Thanks already in advance!
|
|
|
|
|
Create a new instance of the control that you created and give the parent window of the control as the one that you created with the createwindow.
-prakash
|
|
|
|
|
That's exactly what I'm already doing. I create a new HWND with CreateDialogParam() and specify my parent window handle as hWndParent. Yet the newly created HWND is NULL and GetLastError() returns 0 ( ).
Here is an exerpt of the .rc file:
IDD_PVIEWERPANE DIALOGEX 0, 0, 443, 154<br />
STYLE DS_CONTROL | WS_CHILD | WS_VISIBLE<br />
FONT 8, "MS Shell Dlg", 400, 0, 0x1<br />
BEGIN<br />
GROUPBOX "Photo information",IDC_STATIC,7,7,429,140<br />
LTEXT "Title:",IDC_STATIC,13,32,44,8<br />
LTEXT "Static",IDC_TITLE,61,32,98,8<br />
LTEXT "Time taken:",IDC_STATIC,191,32,62,8<br />
LTEXT "Static",IDC_TIMET,255,32,118,8<br />
LTEXT "Path:",IDC_STATIC,13,47,34,8<br />
LTEXT "Static",IDC_PATH,55,47,381,8,SS_ENDELLIPSIS<br />
LTEXT "Dimensions:",IDC_STATIC,13,61,67,8<br />
LTEXT "Static",IDC_DIMENSIONS,81,61,120,8<br />
LTEXT "Zoom factor:",IDC_STATIC,228,61,79,8<br />
LTEXT "Static",IDC_ZOOMF,315,61,98,8<br />
CONTROL "",IDC_RICHEDIT21,"RichEdit20A",ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP,7,78,429,69,WS_EX_CLIENTEDGE<br />
PUSHBUTTON "< Previous",IDC_BPREV,13,17,79,14<br />
PUSHBUTTON "Next >",IDC_BNEXT,357,17,79,14<br />
END<br />
<br />
...<br />
<br />
IDD_PVIEWERPANE, DIALOG<br />
BEGIN<br />
LEFTMARGIN, 7<br />
RIGHTMARGIN, 436<br />
VERTGUIDE, 13<br />
TOPMARGIN, 7<br />
BOTTOMMARGIN, 147<br />
HORZGUIDE, 17<br />
HORZGUIDE, 31<br />
HORZGUIDE, 40<br />
END<br />
...
... and here's my code:
HWnd = CreateWindow(C_PHOTOVIEWER, "", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, PANEWIDTH, 500, NULL, NULL, hInst, NULL);<br />
SetWindowLongPtr(HWnd, GWLP_USERDATA, (LONG_PTR) this);<br />
hPane = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_PVIEWERPANE), HWnd, this->DlgProc, (LPARAM) this);<br />
ShowWindow(HWnd, SW_SHOW);<br />
|
|
|
|
|
I began to read serial communication in Win32 from MSDN. but it confused me.
It dispatched me to synchronization, threads, multithreading, ... ???!!!
the first problem I should ask is what is a thread? what is difference between thread and functions?
and can you give an example of what is the benefit of multithreading?
|
|
|
|
|
Hello,
Fear not fellow programmer for we are here to help you on your quest!
A shall explain briefly what a thread is. You can start exploring this[^] part of MSDN for more information.
A thread is an object in your process that can be sheduled by the OS to take a slice of processor time. The code that is executed is executed parallel with other code of your process. So basically, if you write a multithreaded application, multiple parts (threads) of your application are running at the same time.
By default, your application has just one thread that executes everything after eachother. If you have background tasks or other things that require the user interface to be blocked a long time (such as serial communication), threads are a solution. This object runs seperately from your other code, and therefore cannot block the user interface.
The difference between an normal function and a thread is the way it is executed. A normal function is called by an other part of your code, does its trick and then returns to the caller. When the function is executed, it blocks the caller until it has finished its task.
A thread is also a function, but this function doesn't get called by your code (you can, but normally people don't do this). This function is called by the OS when the thread object is started. It behaves just like the main function. The only difference is that you have to watch out with synchronization and other problems that come with multithreading.
There are some thread classes here on CP that can save you a lot of work. Search for thread and you will find enough information about this stuff.
Hope this helps.
Behind every great black man...
... is the police. - Conspiracy brother
Blog[^]
|
|
|
|
|
A CONNECT PROBLEM WITH CSocket
I have what I think is some very simple CSocket code for a client and a server,
but I'm having difficulty getting it working since it occasionally locks up.
Any advice would be greatly appreciated.
Here's the situation:
I have a client program and a server program. I start them both up, assuring
that the server starts up first and is waiting and ready for the client. They
are both running on the SAME MACHINE.
ON THE CLIENT SIDE
When the client program is started it successfully makes a connection to the server,
sends a simple (command) string to the server, and then retrieves (data) strings
from the Server until it retrieves a special (ENDOFDATA) string from the Server that
indicates that all data has been sent. The Client then sends a final (ENDOFTRANSACTION)
string to the Server, notifying the Server that the whole transaction
is completed and so that the server knows that it can safely close the connection.
ON THE SERVER SIDE
The Server is set up and does its Accept, waiting for a connection from the Client.
When it suceeds in the Accept it then does a ReadString of the first (Command) string from
the Client. The Server then sends the several (data) strings to the Client, followed by
the sending of an (ENDOFDATA) string to the Client. The Server then does another ReadString,
waiting for the (ENDOFTRANSCATION) string from the Client. When the Server receives that
(ENDOFTRANSCATION) string the Server then closes its side of the connection.
And I do this over and over again, testing the connections and the ability
to successfully transfer data betwen the Client and Server. Generally it
works, but not always.
FAILING
When it fails, it does so as follows:
1) The Client enters the Connect method.
2) The Server does indeed Accept the connection from the Client.
3) The Server successfully sets up the sending and receiving Archives.
4) The Server then does the ReadString, waiting to read the initial (Command) string from the Client.
5) But the Server never gets the (Command) string. It waits forever inside the ReadString.
Debugging reveals that the Client is STUCK WITHIN THE Connect METHOD.
Although he Client has performed enough of the Connect method in order to actually establish the
connection (made clear by the fact that the Server Accepts the connection, successfully
establishes the related Archives and starts up the ReadString method) the Client
never does actually complete the processing of the Connect method.
So, the Server is left hanging, waiting for the (Command) string from the Client,
which will never come because the Client never finishes processing the Connect method.
And there it waits, never completing the operations.
Oddly, it works most of the time. If I include TRACE statements in the code it seems to work
more often than if there are no TRACE statements. Also, if I only send a tiny bit of data
(one or two strings) from the Server to the Client then it works more often than if I transfer
lots of strings. But it always inevitably, randomly fails.
Debugging reveals that the place where it's "stuck" is inside the CSocket::ConnectHelper
method,as follows;
BOOL CSocket::ConnectHelper(const SOCKADDR* lpSockAddr, int nSockAddrLen)
{
if (m_pbBlocking != NULL)
{
WSASetLastError(WSAEINPROGRESS);
return FALSE;
}
m_nConnectError = -1;
if (!CAsyncSocket::ConnectHelper(lpSockAddr, nSockAddrLen))
{
if (GetLastError() == WSAEWOULDBLOCK)
{
while (PumpMessages(FD_CONNECT)) << GETS STUCK IN THIS LOOP
{
if (m_nConnectError != -1) << ALWAYS RETURNING m_nConnectError = -1
{
WSASetLastError(m_nConnectError);
return (m_nConnectError == 0);
}
}
}
return FALSE;
}
return TRUE;
}
- - - - - - MY CODE follows
The code below shows the basic, stripped-down versions of the client and server programs.
What am I doing wrong?
// CLIENT CODE
AfxSocketInit();
int nNumberOfTransactions;
for (nNumberOfTransactions = 0 ; nNumberOfTransactions < 1000; ++nNumberOfTransactions)
{
CSocket ClientSocket;
int nPortNumberClient = 0; // 0 means for MFC to select an available port
if (ClientSocket.Create(nPortNumberClient))
{
int nPortNumberServer = 49153;
// Connect to the Server
if (ClientSocket.Connect("68.171.26.117", nPortNumberServer)) // <<< GETS TO HERE AND STOPS
{
CSocketFile SocketFile(&ClientSocket);
CArchive ArchiveSending(&SocketFile, CArchive::store);
CArchive ArchiveReceiving(&SocketFile, CArchive::load);
// Send "GiveMeData" (Command) string to the Server
ArchiveSending.WriteString("GiveMeData\n");
ArchiveSending.Flush(); // to assure sending of the data.
// Get response from Server
while (TRUE)
{
CString strResponse;
ArchiveReceiving.ReadString(strResponse);
if (strResponse.CompareNoCase("ENDOFDATA\n")==0)
{
break;
}
else
{
// It's actual data, do something withit
}
}
ArchiveSending("ENDOFTRANSACTION);
ArchiveSending.Flush();
ArchiveReceiving.Close();
ArchiveSending.Close();
SocketFile.Close();
}
else
{
// Connection failure.
}
}
else
{
// Failed to Create the CSocket.
}
}
///////////////////////////////////////
and here's the server code
///////////////////////////////////////
// SERVER CODE
AfxSocketInit();
CSocket SocketServer;
int nPortNumberServer = 49153;
if (SocketServer.Create(nPortNumberServer, SOCK_STREAM, "68.171.26.117"))
{
if (SocketServer.Listen(5))
{
while (TRUE)
{
// Accept the connection.
CSocket sockRecv;
if (SocketServer.Accept(sockRecv))
{
// Create a file object
CSocketFile file(&sockRecv);
// Create a receiving stream.
CArchive ArchiveReceiving(&file, CArchive::load);
// Create a sending stream.
CArchive ArchiveSending(&file, CArchive::store);
// Get (Command) string that was sent from Client
CString strCommand;
ArchiveReceiving.ReadString(strCommand); // GETS TO HERE AND STOPS
// In response to (Command) string from Server, send Data back to Client
int nCounter;
for (nCounter = 0 ; nCounter < 1000 ; ++nCounter)
{
ArchiveSending.WriteString("Data\n");
}
ArchiveSending.Flush();
// Tell Client that all data has been sent
ArchiveSending.WriteString("ENDOFODATA\n");
// Wait for acknowledgement ("ENDOFTRANSACTION") from Client
// so that I know it's safe to Close
CString strEndOfTransaction;
ArchiveReceiving.ReadString(strEndOfTransaction);
ArchiveReceiving.Close();
ArchiveSending.Close();
}
else
{
// Failed to accept the connection
}
}
}
else
{
// Failed to listen
}
}
else
{
// Failed to create the main socket
}
Roger Garrett
|
|
|
|
|
This is a question only .NET beginner could ask, and I'm sure the answer will be simple.
The background info:
I have an VC++ (MFC) application that I wrote in VS2002. One of the several DLLs that comprise this application is a managed code Crystal Reports viewer. I have created a setup project to make an MSI from all the project outputs from this and the other projects.
The problem:
When I compile this application using VS2002, everything works as expected, and my MSI file has a file size of roughly 11MB. When I compile this application using VS2003, the Crystal Reports viewer quits working, giving me a "Common Language Runtime" error when I attempt to open it, and the MSI file has a file size of roughly 3MB. Also, the Crystal Reports viewer works fine when the application is installed on my development pc, but doesn't work on any other pc I've tried, even if the other pc has the newest .NET Framework installed. My obvious conclusion is that some vital .NET component is being compiled into the VS2002 MSI file, but is not being compiled into the VS2003 MSI file.
I have made sure that the Crystal Reports viewer project has all the correct .NET references specified. I don't know what else to try.
Any suggestions???
|
|
|
|
|
I'm new to MFC and need to access member variables in one class from another class, how do I do that? I was always used to a main function in which I created objects of the classes but now in MFC there is no main or Winmain function?
|
|
|
|
|
You have A Application object Named theApp ,
type of theApp is Your Application Class Derived from CWinApp.
You can Use this Object to hold Variables that can be Accessed everywhere
i.e. theApp.MyVariable = ...
|
|
|
|
|
I tried your suggestion but cannot access that object from anywhere but in the main application file itself?
|
|
|
|
|
To use the global theApp object from anywhere put those two lines into your StdAfx.h:
class CMyApp;
extern CMyApp theApp;
|
|
|
|
|
|
Hello TOliver,
I'm not sure, if I unterstand your question.
- What for classes you have? Derived from MFC-Base-Classes?
- Where is the problem for creating some members as public and access this members ?
- If you need global Objects (Class instances), then I would write some functions/members in the Application File (the file that contains ::InitInstance). Prototypes in the corresponding header. This header is normally included in all other source files of the MFC-Project and you have access to the objects.
Hope that helps
Stephan
|
|
|
|
|
I used the wizard to create a MFC SDI application. In it I already
have various dialog classes but also some generic classes. It is
especially these generic classes which I would like to be able to
access anywhere else (for example from within a dialog class).
|
|
|
|
|
Hi,
would you like to be able to access 'these generic classes',
or in fact objects of 'these generic classes' ?
|
|
|
|
|
well I guess objects because some of these classes have member variables which I need to store a value and then in another class retrieve that value again, but if I don't need to make objects for this then maybe it's better.
Thanx
|
|
|
|
|
OK,
if I'm getting it right, you would like to access member-variables
that reside in one of your classes while you are processing a method
that is a member of another class.
At first:
Classes don't 'have' variables in terms of allocating memory for them. These are only declarations.
If you want to assign values to member-variables you have to create an object of that specific class,
or you have to declare these variables 'static'.
To set an example (guess we are inside the Foo class):
// if you want to get information that a user has entered in a dialog
void Foo::OnFoo()
{
// create your object
FooDlg dlg;
// show it
dlg.DoModal();
// access its members
m_foo1 = dlg.foo1;
m_foo2 = dlg.foo2;
}
// if you want to show some of your information in a dialog
void Foo::OnFoo()
{
// create your object
FooDlg dlg;
// continue initialization
dlg.m_calledFrom = this;
// while FooDlg::m_calledFrom is declared as Foo* m_calledFrom; in the public section of your FooDlg class
// show it
dlg.DoModal();
}
I hope, I didn't miss the point...
Regards
|
|
|
|
|
Hello,
MFC embeds the WinMain function so you don't have to mess with the dirty WIN32 API.
I don't know what kind of data you need to access from what place, but it seems to me that you have trouble with encapsulating data.
It is not a good idea have public member variables in a class. This way, you can never safely assume what value the variable has or when it is safe to write a value to it.
Anyway, if you can explain us from which class you want to access what data in what class, and provide (example) code, we can do more for you.
Behind every great black man...
... is the police. - Conspiracy brother
Blog[^]
|
|
|
|
|
I'll try to explain as best I could. I created an SDI app with the wizard. I need to run an infinite loop (until the user closes the app) to repeatedly call various classes/objects. My first problem is I don't know where to put this loop in MFC, with old c++ I usually put somewhere in main() or such. In my app I have for example an intersection class (represents a simulated traffic intersection) which have various functions and variables. When u click file->new in my app I open up wizard-like dialogs which ask u about how u want the simulation etc. During this time I need to store these values and then later when the simulation begin use these values again. Thus in this wizard-like MFC-dialog class (which handles all the controls) I need to somehow store the enetered/selected values using that intersection class/or object of it, but must also retrieve these values later on from say that infinite loop.
Sorry for all the text.
|
|
|
|
|
Hi,
don't care about the message loop in classes you derived from CWnd.
If you are new in MFC, it might be easier to start a dialog-based application with the wizard.
Just put some edit-controls on it (one for each of your variables) and a button named 'Start' (to start your simulation).
Use the class-wizard (by right-clicking on your controls) to add member-variables and callback-methods to your dialog-class.
In your OnStart() handler call UpdateData(TRUE) to get the entered data into your member-variables, and UpdateData(FALSE) to show the content of your member-variables in the related controls.
I guess the whole stuff you have been asking for happens within
BEGIN_MESSAGE_MAP(CMyDlg, CDialog)
END_MESSAGE_MAP()
and inside the CMyDlg::DoDataExchange(CDataExchange* pDX) method.
Don't care about that code. Just let the class-wizad do that job for you.
Regards
|
|
|
|
|
Depending on your simulation, you should think about modeless dialogs and worker threads...
|
|
|
|
|
When you start (run) a dialog-based application, two objects are created automatically (guess your application is named MySim):
CMySimApp theApp; // this is a global object
CMySimDlg dlg; // this happens within CMySimApp::InitInstance()
You can find this code in the MySim.cpp file.
The message loop of CMySimDlg dispatches all your messages.
You may use all your former global valiables as member-variables of the CMySimDlg class.
Does it help ?
|
|
|
|
|
Thanx. I've already made an SDI app which took a while already, I don't think I should go back to a dialog-based app though.
Thanx anyway
|
|
|
|
|
Ouch .. NOOOOOOO ...
MFC apps are WINDOWS apps, not console apps.
The idea of an infinite loop in main cannot be used in a windows app, since a windows app is itself a loop.
You'll stuck your app, whith an infinite loop, pushing the CPU at 100% for ever, with the only chance, to the user, to kill it.
I suspect your real problem is that you're trying to do with MFC what you ususally do with traditional console application. That's not the way to go, with windows programming.
With MFC, consider this as starting points:
- CYourApp: public CWinApp has global linkage and exist for all the application life. Make its instance (usially a CYuourApp theApp varialble) to have global scope (by declaring it as external in a header included by all files - stdafx.h is good) and you can put any member in it and access it from everywhere.
- virtual CWinApp::Initinstance is called by the MFC embedded WinMain (like the main of traditional consoles) BEFORE the windows message looop is started. Any initialization code can be placed in the Initinstance override.
- Once the messageloop is started, the input devices (keyboard and mouse) are read by the system, and actions are sent as message to the active application's main window where are dispatched to the implementing C++ class member functions through a message map. You can respond to a message by doing any sort of calculation, but NEVER with an infinite loop, or the application will stuck.
- If you need to perform a lengthy operation through a loop, implement a loop like
whiile(your exit condition)
{
::MSG msg;
if (::PeekMessage(&msg, 0,0,0, PM_REMOVE) &&
!::TranslateMessage(&msg))
::DispatchMessage(&msg);
}
That is: give the system a chanche to manipulate input! (and remenber that input cannot be accessed with functions like getch() or cin::get etc. Input becomes messages deliveret to the main window)
(Another more sophisticated way is use a woker thread ... but if you're new to windows programming, multithreaduing is certinly not the starting point!)
- Output cannot be sent to any "stream": you must store it somewhere in your program, and them display it in the window by handling WM_PAINT (ususally with OnPaint )
- if you need a sort of "draw forever" program, you can instantiate a timer (::SetTimer )and respond to it in your main wiandow (OnTimer ) with your loop's body (note BODY, not LOOP: the loop is in Windows, issuing the timer message)
Hope all this may help.
____________
2 bugs found.
> recompile ...
65534 bugs found.
|
|
|
|
|