|
Friends,
Am a windows programmer using MFC and visual c++ tool.Now the thing which is bothering me is .Net has come out and they say that applications can be created in a more Sophisticated and rapid way.Is is really true?How do you see the .Net platform from the application development angle.Will MFC and MFC functions be obsolete or dead in Visual Studio.Net??
Pls answer bit detailedly.
Thanks for reading.
waiting for ur answers.
Bye
|
|
|
|
|
Hi,
Not really! I can bet my life that you will not see C++ and MFC going away any time soon (personally, I hate MFC!). Yes, .NET does bring a lot of changes and I love the architecture of the platform. However, you can still program in the traditional C++ way without using the managed extensions.
Personally the choice of tools really depends on the applications you design. I work in the DSP environment mainly using C++. C++ till this day remains the language of choice when performance remains top priority. Managed code is not suitable for all applications.
However, I would definitely recommend starting to learn and develop using .NET
Pankaj
Without struggle, there is no progress
|
|
|
|
|
Hello again everyone,
A small question for the C++ gurus here I wasgoing through MSDN looking for some information about BEGINPAINT and ENDPAINT API calls. It says that they should only be called in response to WM_PAINT message. However, it does not go on to explain why it should be so? Anyone here knows why it cannot be called outside WM_PAINT.
I was trying to paint a control which needs to be updated with new data every second. If I use ::GetDC(hWnd of control), the update works fine. However, if I use
BEGINPAINT(hWnd of control, pointer to PAINTSTRUCT)
.... painting code
EndPaint(hWnd, PAINTSTRUCT)
Now, it does not update. It just makes one call and subsequent calls have no effect
I really do not understand why it is so. I would really appreciate it if someone sheds some light on it.
Thank you for taking the time to read this. Any help would be greatly appreciated.
Pankaj
Without struggle, there is no progress
|
|
|
|
|
BeginPaint validates the update region for your window.
WM_PAINT messages are only generated when your message queue is empty, and your window has some portion of the window that is invalid. So if you call BeginPaint outside of the WM_PAINT handler, or ValidateRect(NULL) for that matter, you will be validating the entire window, and hence never receive a WM_PAINT message.
As long as you are not having any problems with the call to GetDC, you should continue to use that function. If you are experiencing problems, then you may want to work with the update region yourself, or invalidate portions of your window so that a WM_PAINT message is generated and you can handle the painting in your WM_PAINT handler.
Coincidentally, because the way that WM_PAINT messages are generated and the way that BeginPaint works, you should not generate WM_PAINT messages yourself, you should use RedrawWindow instead.
If you have any other questions don't hesitate to ask.
Good Luck
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!
|
|
|
|
|
pankajdaga wrote:
It says that they should only be called in response to WM_PAINT message. However, it does not go on to explain why it should be so?
Quote from MSDN:
The BeginPaint function automatically sets the clipping region of the device context to exclude any area outside the update region. The update region is set by the InvalidateRect or InvalidateRgn function and by the system after sizing, moving, creating, scrolling, or any other operation that affects the client area. If the update region is marked for erasing, BeginPaint sends a WM_ERASEBKGND message to the window.
This means that device context which BeginPaint initializes has clipping region which allows you to draw only on parts of client are which have been invalidated. If you call BeginPaint when window is not invalidated, your graphics operations will be totally clipped and you won't see anything.
If you insist on using BeginPaint every second, just call InvalidateRect in response to WM_TIMER message (or whatever you're using). However, there's nothing wrong with GetDC; actually, this is the API to use in this case.
Tomasz Sowinski -- http://www.shooltz.com
"Yields falsehood when preceded by its quotation" yields falsehood when preceded by its quotation.
|
|
|
|
|
One more thing I wanted to add, I wrote two articles that explain how windows painting works and how to program with it. There is a beginner and an intermediate article, it may answer some of you questions about paint.
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!
|
|
|
|
|
Hey guys!
Thanks for the reply. Everything is clear now.
I knew that the window was not receiving any paint messages when I used BeginPaint. I just needed to know why I am just crazy for details. Usually, never satisfied if a thing works, I want to know why it does or does not work.
So, I subclassed my abstract canvas class into 2 new classes. One which uses GetDC() and one which uses BeginPaint and EndPaint. So, if I need manual updates I use GetDC(). If I need to do something in response to WM_PAINT, I use Begin and EndPaint
Personally, I did not think generating WM_PAINT myself was not a good idea. This I think is a much simpler and correct solution.
Thanks again. Any new ideas /suggestions welcome
Pankaj
Without struggle, there is no progress
|
|
|
|
|
Does anyone know of any MFC controls of this nature...?
I'm aware of the WTL versions, but I have quickly grown tired of trying to figure out what was going wrong...
I've done all the obvious included wtl/include under project settings and included the nessecary incldes the author suggests...however I still get errors and i'm not interested in trying to figure it out right now...I just don't have the pateince..i'd rather right a owner drawn TAB control myself...using MFC...
So is there any...? Or are these all WTL/ATL...?
Thanx!
"An expert is someone who has made all the mistakes in his or her field" - Niels Bohr
|
|
|
|
|
For a project we use overlapped sockets instead of CSocket (not thread-safe).
Everytime when a socket is accepted:
- the virtual function OnAccept is called, the socket is accepted
- A new thread is started
- new Events are created (m_hStopEvent, m_Read.hEvent, m_Write.hEvent, m_hEvent)
- The socket is 'attached' (see below for code)
but the events still arrive at the listening socket.
the WSAWaitForMultipleEvents goes off.
but WSAEnumNetworkEvents queries 0.
The implementation works fine for UDP (the same socket is used !)
Thanks in advance.
Greetings,
Niko
The code:
socket thread:
int CASyncSocket::SocketFunc()
{
WSAEVENT handles[]={
m_hStopEvent,
m_Read.hEvent,
m_Write.hEvent,
m_hEvent};
WSANETWORKEVENTS netEvents;
DWORD dwWaitResult;
DWORD dwTimeOut;
OnAttach();
for(;;)
{
if(m_ulTimeout == 0)
dwTimeOut = WSA_INFINITE;
else
dwTimeOut = m_ulTimeout;
dwWaitResult = WSAWaitForMultipleEvents(
sizeof(handles)/sizeof(WSAEVENT),
handles,
FALSE,
dwTimeOut,
TRUE);
if(dwWaitResult == WSA_WAIT_EVENT_0+3){
if(WSAEnumNetworkEvents(m_Socket, m_hEvent, &netEvents)!=SOCKET_ERROR)
{
if((netEvents.lNetworkEvents&FD_READ) == FD_READ)
{
_OnReceive(netEvents.iErrorCode[FD_READ_BIT]);
}
if((netEvents.lNetworkEvents&FD_WRITE) == FD_WRITE)
{
_OnSend(netEvents.iErrorCode[FD_WRITE_BIT]);
}
if((netEvents.lNetworkEvents&FD_CLOSE) == FD_CLOSE)
{
_OnClose(netEvents.iErrorCode[FD_CLOSE_BIT]);
}
if((netEvents.lNetworkEvents&FD_CONNECT) == FD_CONNECT)
{
_OnConnect(netEvents.iErrorCode[FD_CONNECT_BIT]);
}
if((netEvents.lNetworkEvents&FD_ACCEPT) == FD_ACCEPT)
{
_OnAccept(netEvents.iErrorCode[FD_ACCEPT_BIT]);
}
}
else
{
int iError = WSAGetLastError();
if(iError == WSANOTINITIALISED ||
iError == WSAENOTSOCK)
{
Close();
}
}
}
else if(dwWaitResult == WSA_WAIT_EVENT_0)
{
break;
}else if(dwWaitResult == WSA_WAIT_EVENT_0+1)
{
_OnReceiveComplete();
}else if(dwWaitResult == WSA_WAIT_EVENT_0+2)
{
_OnSendComplete();
}
else if(dwWaitResult == WSA_WAIT_FAILED)
{
break;
}
else if(dwWaitResult == WSA_WAIT_TIMEOUT)
{
_OnTimeout();
}
else
{
Close();
}
}
_OnClear();
if(bAutoDelete == true)
delete this;
return 0;
}
Accept function:
void CASyncSocket::Accept(CASyncSocket& SocketToAccept) const
{
ASSERT(SocketToAccept.m_Socket == INVALID_SOCKET);
SAcceptedSocket as;
int iLength=sizeof(sockaddr);
sockaddr sockaddress;
as.s = ::WSAAccept(m_Socket, &sockaddress, &iLength, NULL, 0);
as.addr = CIPAddress(sockaddress);
SocketToAccept.Attach(as.s,as.addr);
}
bool CASyncSocket::Attach(SOCKET s, const CIPAddress& Peername)
{
if(s!=INVALID_SOCKET){
Close();
m_Peername = Peername;
m_Socket = s;
if(Init() == true) // starts the thread
{
return true;
}
}
return false;
}
|
|
|
|
|
Niko Tanghe wrote:
Everytime when a socket is accepted:
- the virtual function OnAccept is called, the socket is accepted
- A new thread is started
I might be wrong, but on purpose of a asychronous socket class is that you can handle all sockets with on thread context, so you have:
1) no disadvantages from context switches (very effective)
2) and need less semaphores when accessing common data (also no shared memory block).
in the past I tried to access CAsyncSocket derived from two threads and failed hard. I used a second thread to clear up dead sockets, which failed with a nice assert. Now, I use just one thread context for handling my whole server. The GUI or other stuff _can_ (not has to) still run in different threads.
Hope it helps a bit.
|
|
|
|
|
Hello,
In my CDialog, I use the following line to send a command to a dialog bar:
(((CMainFrame *)AfxGetApp()->m_pMainWnd)->m_SchedDlgBar1).PostMessage(ID_TEST);
My m_SchedDlgBar1 class has the following:
BEGIN_MESSAGE_MAP(CDiagGlobalSched, CDialogBar)<br />
...<br />
ON_COMMAND(ID_TEST, RefreshSchedBar)<br />
END_MESSAGE_MAP()
I have overidden the CMainFrm class's OnCmdMsg to see if this message ever shows up:
BOOL CMainFrame::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo) <br />
{<br />
TRACE1("id:%d ", nID);<br />
if (m_SchedDlgBar1.OnCmdMsg(nID, nCode, pExtra, pHandlerInfo)) return TRUE;<br />
<br />
return CMDIFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);<br />
}
... and based on nID never being equal to ID_TEST (and my code not executing the designated function) it never shows up!? I've looked at examples and my code is exactly how they show it should be.
Where did my message go? Why did it not show up?
thanks!
JennyP
|
|
|
|
|
Use 'PostMessage(WM_COMMAND, ID_TEST)'.
Tomasz Sowinski -- http://www.shooltz.com
"Yields falsehood when preceded by its quotation" yields falsehood when preceded by its quotation.
|
|
|
|
|
Perfect! Thanks Tomasz!
So MSDN says:
BOOL PostMessage( UINT message, WPARAM wParam = 0, LPARAM lParam = 0 );
...and my custom message ID was supposed to be a WPARAM, not a UINT (message)? I'm confused.... but I'll just have to get over it.
JennyP
|
|
|
|
|
WM_COMMAND is message id. WM_COMMAND is sent in response to menu selections, accelerator keys being pressed and some events in controls like edit boxes. wParam contains the command id/control id.
message id != command id.
Tomasz Sowinski -- http://www.shooltz.com
"Yields falsehood when preceded by its quotation" yields falsehood when preceded by its quotation.
|
|
|
|
|
Thanks Tomasz,
I feel bemused by the fact that I couldn't find such a seemingly basic concept in the MSDN... do you know where such a thing would be documented? The MSDN page on CWnd.SendMessage() just says that wParam depends on the command being sent--nothing more.
I would be interested to understand the messaging better.
Thanks!
JennyP
|
|
|
|
|
JennyP wrote:
The MSDN page on CWnd.SendMessage() just says that wParam depends on the command being sent--nothing more.
Sorry, it says that wParam depends on MESSAGE being sent, not command. You should understand the difference if you want to succeed in developing software for Windows.
Tomasz Sowinski -- http://www.shooltz.com
"Yields falsehood when preceded by its quotation" yields falsehood when preceded by its quotation.
|
|
|
|
|
If I have mp3 data reside in memory, can I play mp3 data using DirectShow?
If can't play by DirectShow, how can I play it?
|
|
|
|
|
Does anyone know, why metafiles work extremly slow for graphical filled objects in W2K?
I have a small app, which works fast on WindowsNT 4.0 and Windows XP but it slows down during META_CREATEREGION on Win2K.
|
|
|
|
|
Hi All,
I need to develop an COM Component in VC++ that would put up an entry in the NT application log if the application encounters some error.How do I develop such a COM Component.Is there any method.Please help.
Thanks
Abhishek.
Learning is a never ending process of Life.
|
|
|
|
|
See at WFC Library (CEventLog).
Sonork 100.15206;PavelK
|
|
|
|
|
Hi,
How can I detect an application instance..whether its already running or not?
I am running an application now I want that if that application is running then if I double click that application icon then it should popup the currently running application instance in place of opening a new instance.
Is it possible to detect application instance in VC6?
Thanks in advance
Prateeti
|
|
|
|
|
|
any one try to dev. firewall ?
i need any info about how to write firewall applicatioin
|
|
|
|
|
|
Suppose we execute a SQL query that returns various fields. Now in order to get value of certain field we use following methods:
vtField = pRecordset->Fields->GetItem("Name")->Value;
OR
vtField = pRecordset->GetCollect("Name");
But there are certain queries that do not return any field but a single value e.g
select count(userid) from mytable
Suppose i execute this query and its result is in RecordSet object. Now how can i retrieve this value as this is a single value and is not represented by any field ????
|
|
|
|
|