|
Hi everyone,
When I use Instance Subclassing technique, SetWindowLong() or SetWindowLongPtr() returns NULL pointer. The last error is 50 ERROR_NOT_SUPPORT. I ran the same program on more than 10 XP machines. One of them failed. Does anybody here encounter such problem? Any suggestion?
Thank you in advanced
|
|
|
|
|
From the SetWindowLongPtr documentation:
"If the previous value is zero and the function succeeds, the return value is zero, but the function does not clear the last error information. To determine success or failure, clear the last error information by calling SetLastError(0), then call SetWindowLongPtr. Function failure will be indicated by a return value of zero and a GetLastError result that is nonzero."
The only cases in which these functions should fail are if you pass an invalid window handle, or if you pass an invalid index value (more than the number of bytes associated with the window, or not one of the defined GWL/GWLP values).
|
|
|
|
|
Hi!
Good day
I have this problem about synchronization on namedpipe ...
I have this namedpipe server that allows multiple instances.
The algorithm I have is I'll wait for a client to connect to the namedpipe then spawn a thread which will read the message from the namedpipe. My expectation on the spawned thread is that when the client has disconnected the spawned thread will end also. But when I tried testing my code, the thread count keeps on increasing due to the spawned thread, which i think means I was not able to detect that the client had disconnected or something else
Any help is greatly appreciated.
Below are my codes:
1. Createnamedpipe, wait for a client to connect, and spawned a thread.
<br />
UINT fnRcvMsgsFrmNamedpipeThread(LPVOID pParam)<br />
{<br />
<br />
DWORD dwResult = SUCCEED; <br />
CString strLog( _T( "" ) );<br />
<br />
OVERLAPPED stClientConnectOverLap = {0};<br />
stClientConnectOverLap.hEvent = CreateEvent(<br />
NULL,
TRUE,
FALSE,
NULL);
<br />
if( stClientConnectOverLap.hEvent == NULL )<br />
{<br />
return 0;<br />
}<br />
<br />
HANDLE hEvents;<br />
hEvents = stClientConnectOverLap.hEvent;<br />
<br />
CString strFormatPipeName( _T( "" ) );<br />
strFormatPipeName.Format( "\\\\%s\pipe\mypipename", STR_PERIOD );<br />
<br />
HANDLE hClientReqPipe;<br />
<br />
while ( TRUE )<br />
{<br />
hClientReqPipe = CreateNamedPipe( strFormatPipeName,<br />
FILE_FLAG_OVERLAPPED | PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,<br />
PIPE_UNLIMITED_INSTANCES, <br />
0, 0, 10000, NULL ); <br />
if( hClientReqPipe == INVALID_HANDLE_VALUE )<br />
{ <br />
dwResult = GetLastError();<br />
break;<br />
}<br />
<br />
if( !ConnectNamedPipe( hClientReqPipe, &stClientConnectOverLap ) )<br />
{<br />
if( GetLastError() != ERROR_PIPE_CONNECTED )<br />
{<br />
DWORD dwRet = WaitForSingleObject( hEvents, INFINITE );<br />
if( dwRet != WAIT_OBJECT_0 )<br />
{<br />
dwResult = GetLastError();<br />
break;<br />
}<br />
}<br />
<br />
}<br />
CWinThread *pReadMsgThread = AfxBeginThread( fnReadMsgFrmNamedpipe, (LPVOID) hClientReqPipe );<br />
if( NULL == pReadMsgThread )<br />
{<br />
break;<br />
}<br />
<br />
}<br />
<br />
::CloseHandle( hClientReqPipe );<br />
::CloseHandle( stClientConnectOverLap.hEvent );<br />
<br />
return dwResult;<br />
}<br />
2. Spawned thread
<br />
UINT fnReadMsgFrmNamedpipe(LPVOID pParam)<br />
{ <br />
I32L dwResult = SUCCEED; <br />
CString strLog( _T("") );<br />
HANDLE hClientReqPipe = (HANDLE) pParam;<br />
<br />
OVERLAPPED stClientRecOverLap = {0};<br />
<br />
stClientRecOverLap.hEvent = CreateEvent( NULL,
TRUE,
FALSE,
NULL );
<br />
if( stClientRecOverLap.hEvent == NULL )<br />
{<br />
return 0;<br />
}<br />
<br />
HANDLE hEvents;<br />
hEvents = stClientRecOverLap.hEvent;<br />
<br />
DWORD dwTotalByte, dwRead, dwRet;<br />
<br />
while ( TRUE )<br />
{ <br />
dwTotalByte = 0;<br />
dwRead = 0;<br />
<br />
ReadFile( hClientReqPipe, NULL, 0, &dwRead, &stClientRecOverLap );<br />
dwRet = WaitForSingleObject( hEvents, INFINITE );<br />
<br />
if( dwRet != WAIT_OBJECT_0 )<br />
{<br />
dwResult = GetLastError();<br />
break;<br />
}<br />
if( !PeekNamedPipe( hClientReqPipe, NULL, 0, NULL, &dwTotalByte, NULL ) )<br />
{<br />
dwResult = GetLastError();<br />
break;<br />
}<br />
<br />
if( dwTotalByte > 0 )<br />
{<br />
char* pBuffer = new char[ dwTotalByte + 1 ];<br />
if( !pBuffer )<br />
{<br />
continue; <br />
}<br />
::ZeroMemory( pBuffer, dwTotalByte + 1 );<br />
<br />
ReadFile( hClientReqPipe, pBuffer, dwTotalByte, &dwRead, &stClientRecOverLap );<br />
dwRet = WaitForSingleObject( stClientRecOverLap.hEvent, 10000 );<br />
if( dwRet != WAIT_OBJECT_0 )<br />
{<br />
dwResult = GetLastError();<br />
break;<br />
}<br />
<br />
delete pBuffer;<br />
<br />
}<br />
}<br />
<br />
DisconnectNamedPipe( hClientReqPipe );<br />
CloseHandle( stClientRecOverLap.hEvent );<br />
return dwResult;<br />
}<br />
3. Namedpipe Client
<br />
BOOL fnNewConnectNamedPipe(LPCTSTR lpczPipeName)<br />
{<br />
HANDLE hPipe; <br />
<br />
while (TRUE)<br />
{<br />
hPipe = CreateFile( <br />
lpczPipeName,
GENERIC_READ |
GENERIC_WRITE, <br />
0,
NULL,
OPEN_EXISTING,
0,
NULL);
<br />
<br />
if (hPipe != INVALID_HANDLE_VALUE) <br />
break; <br />
<br />
<br />
if (GetLastError() != ERROR_PIPE_BUSY) <br />
{<br />
printf("Could not open pipe"); <br />
return FALSE;<br />
}<br />
<br />
if ( !WaitNamedPipe(lpczPipeName, 20000) ) <br />
{ <br />
printf("Could not open pipe"); <br />
return FALSE;<br />
} <br />
} <br />
<br />
DWORD dwBytesWritten = 0; <br />
DWORD dwBytesWrite = m_strMsgText.GetLength();<br />
DWORD dwRet;<br />
<br />
OVERLAPPED WriteOverLap = {0};<br />
WriteOverLap.hEvent = CreateEvent(<br />
NULL,
TRUE,
FALSE,
NULL);
<br />
HANDLE hEvent;<br />
hEvent = WriteOverLap.hEvent;<br />
if( !WriteFile(hPipe, m_strMsgText, dwBytesWrite + 1, &dwBytesWritten, &WriteOverLap) )<br />
{<br />
if (GetLastError() == ERROR_IO_PENDING)<br />
{<br />
dwRet = WaitForSingleObject(WriteOverLap.hEvent, 10000);<br />
if (dwRet != WAIT_OBJECT_0)
{<br />
CloseHandle(WriteOverLap.hEvent);<br />
CloseHandle(hPipe);<br />
hPipe = NULL;<br />
return FALSE;<br />
}<br />
}<br />
else <br />
{<br />
CloseHandle(WriteOverLap.hEvent); <br />
CloseHandle(hPipe);<br />
hPipe = NULL;<br />
return FALSE;<br />
}<br />
}<br />
<br />
CloseHandle(WriteOverLap.hEvent); <br />
CloseHandle(hPipe);<br />
hPipe = NULL;<br />
<br />
return TRUE; <br />
}<br />
|
|
|
|
|
Have you tried putting a breakpoint (or several) in the thread proc and watching what is
happening?
The debugger is your friend!
Mark
Mark Salsbery
Microsoft MVP - Visual C++
"Great job team! Head back to base for debriefing and cocktails."
|
|
|
|
|
hi mark,
yup I already did that ...
the funny thing is that the spawned thread is terminating when I run it with breakpoints
and when I put messageboxes.
|
|
|
|
|
After OnInitDialog()of Dialog-based applications, how the dialog is getting the message from Windows. Is the dialog polling or by wake up?
Best Regards,
Suman
|
|
|
|
|
AFAIK, the application waits until a message is received. So, no CPU time is consumed during this wait (not like if you were actively polling).
|
|
|
|
|
rp_suman wrote: After OnInitDialog()of Dialog-based applications, how the dialog is getting the message from Windows. Is the dialog polling or by wake up?
If it's a modal dialog then DoModal has a message loop for processing messages, and if it's a non modal dialog box then m_pMainWnd of CWinApp class helps in doing that. CWinApp::Run function has a message loop that processes messages on m_pMainWnd and this is the reason my we have to set m_pMainWnd in InitInstance member function of CWinApp derived class.
|
|
|
|
|
Right, so I would like to put a custom control into the status bar in Windows Explorer while my namespace extension is showing, much like you would if you were writing your own MFC/ATL/WTL-based program.
However, all I've managed to find anywhere are articles on how to do it in your own MFC/ATL/WTL-based program or how to use IShellBrowser::SetStatusTextSB.
Is what I want to do possible?
|
|
|
|
|
Hai All,
I'm creating a dialog based application.I want the first dialog that gets created from Inintinstance of App to be a modeless one.My problem is that if i use create() i've to declare the dialog object,with a scope in the entire application(ie, on heap).If I declare it in the demo2.h.I've tried so but getting erors when I'm trying to declare an object of app say myapp.
Please suggest me where I went wrong.Also please tell me is it possible to have the first window in an application to be a modless one.If so pls tell me the way to do that.
Thanks in advance
Robs here
|
|
|
|
|
What is your puropse of doing that? Making the dialog [from a dialog-based app] be modeless is meaningless unless you specify the aim.
Anyway, if you look at the InitInstance method, you will see that this method will not return until CMyDlg::DoModal returns. Note that the application will exit if the InitInstance exits in a dialog based app. So if your dlg were modeless you'd not do much for him as the app would exit just after the dlg displayed.
Still you may simulate smth like what you want. The code in InitInstance might look like so;
CMyDlg *pDlg = new CMyDlg();
pDlg->Create(CMyDlg::IDD, NULL);
// you may use CWnd::GetDesktopWindow() instead of NULL if it make sense
pDlg->ShowWindow(SW_SHOW);
CWinThread::Run();
// Here CWinThread::Run enters a message loop and thus will prevent the app exit instantly.
The only remaining point was to exit the app when the dialog closed. So you should have PostQuitMessage inside CMyDlg::PostNcDestroy;
PostQuitMessage(0);
delete this;
Once again, these all are note a good practice...
--
=====
Arman
|
|
|
|
|
Hi
maybe this can help u
**************************************************************************************
BOOL CDlgMaxApp::InitInstance()
{
// Standard initialization
// If you are not using these features and wish to reduce the size
// of your final executable, you should remove from the following
// the specific initialization routines you do not need.
CDlgTestDlg* pDlg = new CDlgTestDlg;
pDlg->Create( IDD_DLGMAX_DIALOG );
pDlg->ShowWindow( SW_SHOW );
m_pMainWnd = pDlg;
// Since the dialog has been closed, return FALSE so that we exit the
// application, rather than start the application's message pump.
return TRUE;
}
int CDlgMaxApp::ExitInstance()
{
// TODO: Add your specialized code here and/or call the base class
delete m_pMainWnd;
return CWinApp::ExitInstance();
}
int CDlgMaxApp::Run()
{
// TODO: Add your specialized code here and/or call the base class
return CWinApp::Run();
}
**************************************************************************************
InitInstance returns TRUE to start the message pump, if returns FALSE then will not call Run()
Adrian Brutus
|
|
|
|
|
Yes, this is even better. I missed to do
m_pMainWnd = pDlg;
The point is that CWinApp::Run doesn't enter a message loop if m_pMainWnd is NULL which is not the case now.
Thanks.
--
=====
Arman
|
|
|
|
|
Hai Arman Z. Sahakyan ,
Thanks for you reply.I'm new to this GUI part.Correct me if I'm wrong.
My aim is to make onscreen keyboard.For that I need to type in the alphabets and other things to the application ,say,notepad using the onscreen keyboard.this is my aim.Please correct me if my logic don't work.Is there any better way?
Thanks in advance
Robs here
|
|
|
|
|
Well, I don't think you need all this stuff about modeless dialogs. You can use ordinary dialog based application (with DoModal). On the other hand, if you want your keyboard to be on the top of all other windows, then use SetWindowPos inside OnInitDialog like so;
SetWindowPos(&CWnd::wndTopMost, x, y, width, height, SWP_SHOWWINDOW);
--
=====
Arman
|
|
|
|
|
Hai Arman,
My requirment is that I want to create an "ONSCREEN KEYBOARD" application .It should work excatlly like the physical keyboard.For example suppose if we run the "ONSCREEN KEYBOARD" application , now change the focus to an already opened window say notepad the "ONSCREEN KEYBOARD" dialog should not be minimized.It should show as it is inactive but at the same time if the cursor now focused on notepad and again the user clicks soame keys with the mouse on the "ONSCREEN KEYBOARD" application ,the keys pressed (be a,then a should be displayed inside the notepad)should be displayed in the note pad.This is my intention.
Regards
Robs here
|
|
|
|
|
robshere wrote: For example suppose if we run the "ONSCREEN KEYBOARD" application , now change the focus to an already opened window say notepad the "ONSCREEN KEYBOARD" dialog should not be minimized.It should show as it is inactive but at the same time if the cursor now focused on notepad and again the user clicks soame keys with the mouse on the "ONSCREEN KEYBOARD" application ,the keys pressed (be a,then a should be displayed inside the notepad)should be displayed in the note pad.This is my intention.
And what makes you think a modeless dialog is required for this? A dialog's mode (i.e., modal, modeless) governs how the dialog behaves in relation to its parent window, not windows of other processes.
"A good athlete is the result of a good and worthy opponent." - David Crow
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
Hai DavidCrow,
Sorry,my logic was wrong.I got it right now.I want to set the focus from the current application to other application.This is how I'm working on.Thanks for your valuable information and your precious time.I really apprictiate ur kindness for answering me.Any how it gave me very valid informations.
Regards
Robs here
|
|
|
|
|
robshere wrote: I got it right now.
Glad you got it going.
"A good athlete is the result of a good and worthy opponent." - David Crow
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
Hi,
Can you suggest me if we can convert existing ActiveX DLL( created in Visual Studio 6.0) to ActiveX EXE?
Thanks in Advence.
Thanks,
Anand.
|
|
|
|
|
Once again, your question doesn't make any sense: an ActiveX exe doesn't exist. You just have a plain executable. Of course, you can use an activeX inside an executable.
You could still restart a new project and copy paste some code or classes but that's not very efficient.
Also, as I already asked, more information would be usefull: what does this activeX do ? What are you trying to achieve exactly.
|
|
|
|
|
Hi,
Actually I am having DLL with ActiveX interface exposed in it, which I am invoking through script. Previousle it was getting included in IEXPLORE memory space, but now I want it as a stand alone application which will run in its seperate Memory space but still want to invoke through scrpit.
Hope this makes sense now.
Thanks,
Anand.
|
|
|
|
|
And why don't you simply create a simple application that just wraps the ActiveX ? You just add the control to your application and write some code to handle it.
|
|
|
|
|
Yea .. I was thought of that, but i dont want to change the ProgID in script so the same ActiveX interface want to call from script, but that interface should run separately in separate Memory space ... i think to convert DLL to Executable is the better option, so i just wanted to know wheather we can convert DSP file so that it will get compiled into EXE.
Anand.
|
|
|
|
|
Anand Todkar wrote: but i dont want to change the ProgID in script so the same ActiveX interface want to call from script, but that interface should run separately in separate Memory space
Could you clarify that because I am completely lost...
Anand Todkar wrote: i think to convert DLL to Executable is the better option
I don't think it is a good idea (but I don't really see what you are doing neither). Because trying to convert two things that are unrelated doesn't make any sense to me. It is a little bit like if you were asking how to convert the engine of your car into a car . An activeX is a component of your application like the engine is a component of your car (I know that is a poor analogy but it shows you the logic).
Anand Todkar wrote: so i just wanted to know wheather we can convert DSP file so that it will get compiled into EXE.
If you really want to do that, you'll need to restart a new project, copy the file that you want to reuse, and probably modify quite a lot of things in order to make it work.
EDIT: sorry, the blockquotes were not at the right place
|
|
|
|
|