|
Gary R. Wheeler wrote:
so that the compiler validates how you've declared the functions (foo.h) with how you've defined them
but it doesn't do this. it doesn't care if MyFunc is defined differently than the implementation. try it.
-c
“losinger is a colorizing text edit control”
-- googlism
|
|
|
|
|
Including foo.h would make sure there aren't any conflicts between declarations and actual functions. Of course the linker will eventually catch any typos in either file.
|
|
|
|
|
markkuk wrote:
Including foo.h would make sure there aren't any conflicts between declarations and actual functions.
actually, it wouldn't. because you can overload functions in C++, the compiler will ignore any differences. and that's the basis of the problem - the compiler really doesn't care. the only reason to include foo.h would be for my own benefit (ignoring the extern "C" linkage stuff)
-c
“losinger is a colorizing text edit control”
-- googlism
|
|
|
|
|
If you also put the extern "C" on the actual functions, then the compiler will do the check for differences. When I setup a C++ source file that I want to have extern "C" functions, I always also add this to the actual functions to make sure that there is a match. If I leave off the extern "C" on the actual function and it doesn't match the prototype, I won't get an error until linking.
Best regards,
John
|
|
|
|
|
Hmm. I think I see where the confusion lies. With C++ and overloading, you're right. Having foo.h does not guarantee that the implementation in foo.cpp will be verified by the compiler, unless you use the 'extern "C"' construct. I believe Visual C++ compiles sources named .C as if they are 'extern "C"' by default.
In any case, I think it's better stylistically to have a header file than not. Other people looking at the code will expect to see it. If you don't include the header file, then other folks reading the code will have to look at each use of the function(s) to see how they are used. Also, I normally consider the header file to describe the controls for a black box (the 'interface' to the black box) while the source file is the 'implementation' of the black box. I then document changes to the interface in the header file, and changes to the implementation in the source file.
Just my $0.02.
Software Zen: delete this;
|
|
|
|
|
Hi!
I'm still working on my assignment to modify my chat program to have the capability to transfer files as well as messages.
I put a button on the client side, and when the person clicks on it, the file dialog box is supposed to open, and the person can choose the file to send.
I get the dialog box, the program gets the file path.. reads the file ok.. and now it is being sent to the server.. (I've made progress!)
However, the server gives an error, "An attempt was made to access an unnamed file past its end".
If anyone knows what the error means exactly, or can give any suggestions about it... please respond.
Thank you..
|
|
|
|
|
How are you reading and writing the file? If you are chopping it up and sending it you may be reading into the file past its end same as when you receive the file.. could you post some code?
|
|
|
|
|
Thank you so much for replying to me.
The following is my send code when the button is clicked. I found most of it on this site:
void CMainFrame::OnSFile() <br />
<br />
{<br />
MessageBox("File Transfer");<br />
<br />
CSocket cSocket;<br />
cSocket.Create();<br />
cSocket.Connect("127.0.0.1", 700);<br />
<br />
csocketfile sf(&cSocket);<br />
CArchive ar(&sf, CArchive::store);<br />
<br />
<br />
<br />
static char BASED_CODE szFilter[] = "All Files (*.*)|*.*||";<br />
<br />
CString strPath;<br />
<br />
CFileDialog m_ldFile(TRUE,".*","*.*",OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFilter);<br />
<br />
<br />
if (m_ldFile.DoModal() == IDOK)<br />
{<br />
<br />
strPath = m_ldFile.GetPathName();<br />
CFile myFile(strPath,<br />
CFile::modeRead | CFile::typeBinary); <br />
<br />
DWORD length = myFile.GetLength();<br />
char *data = new char[length];<br />
myFile.Read(data, length);<br />
<br />
ar << myFile.GetFileName();<br />
ar << length;<br />
ar.Write(data, length);<br />
delete[] data;<br />
myFile.Close();<br />
<br />
}<br />
<br />
}
--------------------------------------------------------------------------
On the server side, I've put this as the receiving code. Maybe I've put it in the wrong place?
There is a void
CClientSocket::OnReceive(int nErrorCode) which is an overrided method
from the CSocket class. So basically whenever the socket receives
something, it kicks off the OnReceive code. I've put it there.
Also, in my Send code, there is a line commented off, and replaced with a hardcoded statement. Before I did that I was getting another error, "An unknown error occurred while accessing an unnamed file"
I'm going to try changing around a few things, but if you have any suggestions on thoughts on this, please let me know.
Thank you so much.
|
|
|
|
|
Sorry for this elementary question -- but I'm having trouble finding a simple answer.
I am planning to work with another developer who uses Visual C++ 6.0 to do his coding. I would like to be able to compile the source code that he sends to me. For my limited application (just compiling someone else's work, not doing any coding myself) will Visual C++ 6.0 Standard work as well as the Professional edition? What are the substantive differences between Standard and Pro?
Thanks.
|
|
|
|
|
|
Hi.
I am in the process of implementing a IOCP on a Windows program. The program works as designs using WSAAsyncSelect I/O.
Under IOCP, for some reason the call to function GetQueuedCompletionStatus(...) returns immediately even when I specify INFINITE wait. Thus, the cpu usage is aways at 100%. This occurs during program initialization as I want the program to create a completion port on startup. Again, the creating of the completion port does not run an error. The creation of the worker thread to handle completion events and where GetQueuedCompletionStatus(...) resides does not run an error.
However, for some reason, GetQueueCompletionStatus(...) returns immediately even with the INFINITE parameter. This occurs while the completion port is empty, or there are no sockets associated with it yet. How is that possible? And each time it returns, the byte transfer is always 0.
Please post if you have any suggestion as to where to begin debugging.
Thanks,
Kuphryn
|
|
|
|
|
The API for GetQueuedCompletionStatus() states "If dwMilliseconds is INFINITE, the function will never time out. If dwMilliseconds is zero and there is no I/O operation to dequeue, the function will time out immediately." It further states that, "if a socket handle associated with a completion port is closed, GetQueuedCompletionStatus returns ERROR_SUCCESS, with lpNumberOfBytes equal zero."
INFO: Design Issues When Using IOCP in a Winsock Server[^]
"The greatest danger to humanity is humanity without an open mind." - Ian Mariano
http://www.ian-space.com/
|
|
|
|
|
Hello
I am trying to make the example at MSDN about explicit linking to DLLs
to work but i have some problems.
The example i am talking about:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore/html/_core_Link_Explicitly.asp
My question is: Where is HINSTANCE and LPFNDLLFUNC1 defined?
Do I need to include some particular headerfile/s or something else?
Thanks for your help
Thomas, Uppsala University Student, Sweden
|
|
|
|
|
tUpp wrote:
My question is: Where is HINSTANCE and LPFNDLLFUNC1 defined?
LPFNDLLFUNC is defined in the example:
typedef UINT (CALLBACK* LPFNDLLFUNC1)(DWORD,UINT);
That "prototypes" the function in the DLL.
HINSTANCE is defined #include ing <windows.h> (it's actually in a file included by windows.h, windefs.h, I think.)
If you want to use the example, you have to: Create a DLL, which exports the hypothetical function, and make sure the sample .exe you create can find it (e.g., place the DLL in the same folder.)
Read more about DLL Frequently Asked Questions[^]
Normally, you'd export the function in a header (.h) file, stating the function comes from an imported DLL:
__declspec(dllimport) UINT function(DWORD,UINT);
And you would link to the library. Explicitly linking means you don't have the headers, but you know the function(s) you wish to call, hence that typedef .
-- ian
|
|
|
|
|
Hi,
i have a dialog based program(MFC...)and i would like to add a tool bar, how can i do that?
|
|
|
|
|
quite easy.
see toolbar on MainFrame, slightly modified it a little bit, it will be on ur Dialog-box
includeh10
|
|
|
|
|
Normally messages are cought into a so called Message Loop and are parsed using the TranslateMessage and DispatchMessage. The DispatchMessage does two things:
1 - it calls the right Window procedure
2 - it posts the return value back to the os
Well I want to redesign option 1, but I don't want to redesign option 2, so does anyone know what DispatchMessage really does? Maybe WTL/ATL have also there implementations, so if anyone knows where these are, I would be pleased if anyone tells me where.
Sjoerd van Leent
LPCTSTR Dutch = TEXT("Double Dutch ");
|
|
|
|
|
If you poke around in the headers you'll see some interesting things.
MFC, ATL, and WTL use #define s to set up message handling for their window classes. I think you're really wanting to implement your own message handling for your window classes. DispatchMessage() is a Win32 API that [MSDN] "dispatches a message to a window procedure. It is typically used to dispatch a message retrieved by the GetMessage function." You can't really roll your own version of DispatchMessage.
Take a look at this interesting snippet from <atlwin.h> line 1524:
#define BEGIN_MSG_MAP(theClass) \
public: \
BOOL ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lResult, DWORD dwMsgMapID = 0) \
{ \
BOOL bHandled = TRUE; \
hWnd; \
uMsg; \
wParam; \
lParam; \
lResult; \
bHandled; \
switch(dwMsgMapID) \
{ \
case 0:
You should probably research it a bit before you implement your own, because you'll have to be tight on processing windows messages using Win32 wrapped by C++.
-- ian
"The greatest danger to humanity is humanity without an open mind." - Ian Mariano
http://www.ian-space.com/
|
|
|
|
|
imariano wrote:
...you'll have to be tight on processing windows messages using Win32 wrapped by C++.
I know about thunking or joining, or storing the this pointer, but I'm just curious, it should be possible...
LPCTSTR Dutch = TEXT("Double Dutch ");
|
|
|
|
|
Here is the implementation for DispatchMessage from WINE.
LONG WINAPI DispatchMessageW( const MSG* msg )
{
WND * wndPtr;
LONG retval;
int painting;
WNDPROC winproc;
if ((msg->message == WM_TIMER) || (msg->message == WM_SYSTIMER))
{
if (msg->lParam)
{
if (!TIMER_IsTimerValid(msg->hwnd, (UINT) msg->wParam, (HWINDOWPROC) msg->lParam))
return 0;
return CallWindowProcW( (WNDPROC)msg->lParam, msg->hwnd,
msg->message, msg->wParam, GetTickCount() );
}
}
if (!(wndPtr = WIN_GetPtr( msg->hwnd )))
{
if (msg->hwnd) SetLastError( ERROR_INVALID_WINDOW_HANDLE );
return 0;
}
if (wndPtr == WND_OTHER_PROCESS)
{
if (IsWindow( msg->hwnd ))
ERR( "cannot dispatch msg to other process window %x\n", msg->hwnd );
SetLastError( ERROR_INVALID_WINDOW_HANDLE );
return 0;
}
if (!(winproc = wndPtr->winproc))
{
WIN_ReleasePtr( wndPtr );
return 0;
}
painting = (msg->message == WM_PAINT);
if (painting) wndPtr->flags |= WIN_NEEDS_BEGINPAINT;
WIN_ReleasePtr( wndPtr );
SPY_EnterMessage( SPY_DISPATCHMESSAGE, msg->hwnd, msg->message,
msg->wParam, msg->lParam );
retval = CallWindowProcW( winproc, msg->hwnd, msg->message,
msg->wParam, msg->lParam );
SPY_ExitMessage( SPY_RESULT_OK, msg->hwnd, msg->message, retval,
msg->wParam, msg->lParam );
if (painting && (wndPtr = WIN_GetPtr( msg->hwnd )) && (wndPtr != WND_OTHER_PROCESS))
{
BOOL validate = ((wndPtr->flags & WIN_NEEDS_BEGINPAINT) && wndPtr->hrgnUpdate);
wndPtr->flags &= ~WIN_NEEDS_BEGINPAINT;
WIN_ReleasePtr( wndPtr );
if (validate)
{
ERR( "BeginPaint not called on WM_PAINT for hwnd %04x!\n", msg->hwnd );
RedrawWindow( msg->hwnd, NULL, 0,
RDW_NOFRAME | RDW_VALIDATE | RDW_NOCHILDREN | RDW_NOINTERNALPAINT );
}
}
return retval;
}
Build a man a fire, and he will be warm for a day Light a man on fire, and he will be warm for the rest of his life!
|
|
|
|
|
I also looked into atlapp.h of WTL70 there is also another type of function which does this.
But do you've also the TranslateMessage function, and other functions which apply to a message loop. I guess that what I really want to do is fading the CALLBACK out of sight.
LPCTSTR Dutch = TEXT("Double Dutch ");
|
|
|
|
|
Never thought to look @ Wine Heheh. Still, quite informative that code snippet, and the psuedocode one below from MSJ...which looks like it still allows for 16-bit (!) thingamadoodles.
TranslateMessage allows for "preprocessing" of Virtual key messages into character messages, which are then posted to the calling thread's message queue.
|
|
|
|
|
Got this code out of a MSJ from 1997
MS Systems journal example:
LONG DispatchMessageA( CONST MSG *lpmsg )
{
return DispatchMessageWorker( lpmsg, 1 );
}
LONG DispatchMessageWorker( CONST MSG *lpmsg, BOOL fAnsi )
{
if ( lpmsg->message == 0xFFFE0000 )
{
_UserSetLastError( ERROR_INVALID_PARAMETER );
return 0;
}
if ( lpmsg->hwnd )
{
pWnd = @ValidateHwnd( lpmsg->hwnd );
if ( !pWnd )
return 0;
}
else
pWnd = 0;
if ( (lpmsg->message != WM_TIMER) && (lpmsg->message != WM_SYSTIMER) )
{
begin_normal_message:
if ( pWnd == 0 )
return 0;
DWORD save_wParam = lpmsg->wParam;
if ( (lpmsg->message != WM_PAINT) && !(pWnd->someFlags9E & 4) )
{
if ( IsWindowUnicode( lpmsg->hwnd ) )
{
if ( fAnsi )
RtlMBMessageWParamCharToWCS( lpmsg->message, save_wParam );
else
RtlWCSMessageWParamCharToMB( lpmsg->message, save_wParam );
}
if ( 0 == (pWnd->pfnWndProc & 0x80000000) )
{
pWnd->pfnWndProc( lpmsg->hwnd, lpmsg->message,
lpmsg->wParam, lpmsg->lParam );
}
else
{
pfnWowWndProcEx( lpmsg->hwnd, lpmsg->message, save_wParam,
lpmsg->lParam, lpmsg->message, pWnd->0x90 );
}
}
else
{
if ( fAnsi )
_RtlMBMessageWParamCharToWCS( lpmsg->message, save_wParam );
_NtUserDispatchMessage( lpmsg );
}
lpmsg->wParam = save_wParam;
}
else
{
TIMERPROC pfnTimerCallback = lpmsg->lParam;
if ( pfnTimerCallback == 0 )
goto begin_normal_message;
if ( lpmsg->message == WM_SYSTIMER )
return _NtUserDispatchMessage( lpmsg );
return pfnTimerCallback( lpmsg->hwnd,
lpmsg->message,
lpmsg->wParam,
GetTickCount() );
}
}
LPCTSTR Dutch = TEXT("Double Dutch ");
|
|
|
|
|
Im designing a simple interface using MFC. When i add a list box to the main dialog, build it and then run it, the exe pops-up and works as expected. If i then go to the classwizard and add a Control-Clistbox variable to this list box and rebuild it and run it, nothing happens. The exe doesn turn up at all, the mouse pointer just changes to hour-glass and then back to the pointer. Anybody know why?
Ayush
|
|
|
|
|
If you just add the CListBox to the class and not the dialog, you're only getting a class member which is not tied to anything in the dialog, and it's never going to show up if you don't do some extra work.
If you want to wire up the list box into your dialog class, do what you did to add the dialog to the form, then use the ClassWizard to associate the list box to a class member.
Using ClassWizard[^], and the CListBox reference[^]
-- Ian
|
|
|
|
|