|
Hi Guys
I am creating a mutex in one application and try to open in other application but it is not opening in other application
may i know what could be the reason
thanks in advance
RYK
|
|
|
|
|
Can you post the code (for both apps) relating to opening the mutex?
On failure, what error code is GetLastError() returning?
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Hi This is the code what i have used for creating mutex and opening mutex
SECURITY_ATTRIBUTES SecAtt;
SecAtt.nLength = sizeof(SECURITY_ATTRIBUTES);
SecAtt.bInheritHandle = true;
SecAtt.lpSecurityDescriptor = NULL;
m_hMutex = CreateMutex(&SecAtt ,FALSE,_T("Global\\DeviceFilterWriteNotification"));
in a Function the same application i have written some pice of code
::WaitForSingleObject(m_hMutex ,INFINITE);
// some percess is executing
if(ReleaseMutex(m_hMutex)) //allows ervice to access status file
WriteLog("Write Mutex Reset Successfully");
else
WriteLog("Failed to Release write Mutex");
in other application which is a service i am opening the Mutex by this way
HANDLE hWrite= OpenMutex(NULL,FALSE,_T("Global\\DeviceFilterWriteNotification"));
ReleaseMutex(hWrite);
Thanks in advance
RYK
|
|
|
|
|
What happens if you specify access flags:
HANDLE hWrite= OpenMutex(MUTEX_ALL_ACCESS, FALSE, _T("Global\\DeviceFilterWriteNotification"));
If that fails, what is the error code?
Also, after OpenMutex(), the thread doesn't own the mutex so there's no need to release it.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
VC_RYK wrote: SecAtt.lpSecurityDescriptor = NULL
Try specifiying a security descriptor - use the same one in both your service and your application. If your service is running in the system account, the default security descriptor is NOT the same as the default for the application. This mismatch may be your problem.
Judy
|
|
|
|
|
Hello everybody,
I am in the middle of a project that involves hooking the file/open save and browse for folder dialog boxes of he currently installed windows applications and manipulate them by sending windows message codes.
I am stuck with a problem in doing that.
I have been able to hook into the file/open save dialog boxes and manipulate them , when the applications (Notepad,Wordpad,Adobe Acrobat etc.) uses the windows common control dialogs (i.e Common Dialog Box Library).The window class type of these type of dialogs is #32770(Dialog).
But the microsoft office suite doesnot use this library to generate the file open / save dialogs. The class type for the
MS Office dialogs is "bosa_sdm_Microsoft Office * " , where the " * " stands for Word,Excel,Access etc.
The MSDN states that
The following are messages that a hook procedure can send to an Explorer-style Open or Save As dialog box.
CDM_GETFILEPATH
CDM_GETFOLDERIDLIST
CDM_GETFOLDERPATH
CDM_GETSPEC
CDM_HIDECONTROL
CDM_SETCONTROLTEXT
CDM_SETDEFEXT
But unfortunately sending these messages using
LRESULT SendMessage(
HWND hWnd, // handle to destination window
UINT Msg, // message
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
);
won't do any good in case of Microsoft Office dialogs.
The MSDN also doesnot state what messages I can send to the office dialogs from the hook function to manipulate them or retrieve retrieve information regarding the current folder/file path within the office dialog.
So I am requesting everybody here to provide me the required guidance.
I will be greatful if you people can provide anything useful.
Thanks and regards,
|
|
|
|
|
Microsoft applications, like all other applications, are not required to use the common dialogs.
Maybe they publish the information you need, but they're certainly not required to do so.
Good luck!
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Here are the basic steps as I understand them to "hook" a dialog in some application. I personally never use actual Windows Hooks, as from my limited experience, they are slow, with a lot of overhead, and complicated to discourage their use.
The three basic things needed are:
1) DLL injection
2) Windows Subclassing
3) Hooking the application import table.
The last item goes by different names and does not involve actual Windows Hooks.
Maybe you know some of this already:
First You need to inject your code into the process address space of the target application. This means putting it in a DLL and then calling some function InjectDLL(targ_hwnd,"mydll.dll"). There are numerous downloadable libaries for DLL injection. Do a search on CodeProject.
Then, within your DLLMain, presumably you'll do a search for the main window of the target application, using FindWindow, or whatever. At that point, you subclass that window with your own WndProc. You do this by calling SetWindowLong with the appropriate parameters. You also need to save the previous wndproc it returns so you can call it from your own. Your new wndproc is a message handler, looking at messages before the existing WndProc recieves them.
So your task is to hook into some dialog of this application. Presumably this dialog is activated from some menu item are tool bar button in the main window. Use SpyXX to find out the message being sent to the Main Window when this toolbar button or menu item is selected. Then you will intercept that message in your new WndProc. When you receive that message all you will do is set some Boolean, say bFindFileDlg to TRUE.
That brings us to the next step - hooking the application import table. If you can figure out how to get the Window Handle of the dialog through some message sent to the main window, then this step isn't necessary. All you need is the dialog hwnd so you can subclass it, just like you subclassed the main window procedure. But if there is no such message, then you need to find this dialog hwnd by intercepting the Win32 calls that are made it initialize any dialog.
For examples, you could replace SetDlgItemText (likely to be called in any dialog box init), with your own version, which could go like this:
WINUSERAPI BOOL WINAPI r_SetDlgItemTextA(HWND a,int b,LPCSTR c) {
if (bFindFileDlg) {
char txt[80];
GetWindowText(a, txt, 80};
if !strcmp(txt,"File Open") {
SetProp(a,"PrevWndProc",(HANDLE)
(WNDPROC)SetWindowLong(a, GWL_WNDPROC, (LONG)MyDlgProc));
bFindFileDlg = FALSE;
}
return SetDlgItemTextA( a, b, c);
}
Now you need to inject the function above in the slot of the app's import table for SetDlgITemTextA. Again there are many libraries to do this.
For example, there is HookImportFunctionByName. However, note that this function only hooks the import table of one specific exe or dll you specify. What you want is a recursive version that replaces the entry for every DLL loaded by the application. In all liklihood, the main exe isn't making the call to SetDLgItemText directly, but rather throught some dll (e.g. MFC).
I had to write my own recursive version of HookImportFunctionByName but undoubtedly there's something out there already written that does it for you.
To know what win32 calls are being made, it helps to have a debug version of it, or write your own, hooking every single win32 call.
There's probably a half dozen other crucial issues to be aware of, but I guess you'll have to find those out for yourself. Well, one other thing. In your subclassed WndProc, make sure to restore the original WndProc in the WM_DESTROY message.
|
|
|
|
|
FWIW, its not only win32 functions that can be hooked. If you know MFC calls, and their parameters, you can hook the import table for them in the same way. Also, the executable format is the same for all windows binaries, regardless if they're .NET, managed, or whatever - at least that's my understanding. Everything is just a wrapper for the win32/platformsdk.
|
|
|
|
|
Sir,
Sorry for my late reply. I appreciate your effort in helping me out. I have already implemented the hooking part as you have described and it is working well for application using the windows common dialog library.
But in case of MS OFFICE dialogs and Browse for Folder dialogs things are becoming critical and confusing!
My obstacle is to retrieve:
1.The current directory path of a selected file or folder
within an MS Office File Open / Save dialog.
2.Is it possible to retrieve the current directory path ,
when no selection is made by the user ? Like when the dialog is just initialized or when the user changes directory using up and back button ?
3.To paste the retrieved directory within the filename textedit cum combobox of the dialog ?
4.How to retrieve the same information in case of browse for folder dialog.
I used spy++ to detect individual controls within the office dialog. But it appears that the whole dialog is embedded within a single unit having CTRL ID 0 !
I cannot use MFC classes in this project. The project specs states that only Win32 C code is allowed.
Thanks and regards,
|
|
|
|
|
Having read a number of articles on waking a PC up from hibernation, I have tried to do this using the following code:-
hTimer = (HANDLE)CreateWaitableTimer(NULL, TRUE, "My Waitable test Wake Up Timer");
unsigned threadId;
HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, &wakeupWatchThread, &hTimer, NULL, &threadId);
return TRUE; // return TRUE unless you set the focus to a control
The worker thread code is:-
unsigned __stdcall wakeupWatchThread(void* dummy)
{
LARGE_INTEGER lElapse;
int i1 = 63000;
int i2 = 100000;
lElapse.QuadPart = - (i1*i2); // About 10.5 mins elapsed
BOOL result = SetWaitableTimer(hTimer, &lElapse, 0, TimerProc, NULL, TRUE);
DWORD dwError;
if(result == FALSE)
dwError = GetLastError();
for (int i = 0; i < 10; i++)
SleepEx(INFINITE, TRUE);
return 0;
}
and the timer completion code is :-
void CALLBACK TimerProc(LPVOID lpArgToCompletionRoutine,
DWORD dwTimerLowValue,
DWORD dwTimerHighValue)
{
CTime tNow(CTime::GetCurrentTime());
CString szTime, szMsg;
szTime = tNow.Format( "%A %H:%M" );
szMsg.Format("Waitable timer expired at %s",szTime);
AfxMessageBox(szMsg);
}
My problem is that the PC doesn't wake up !! (the last parameter of SetWaitableTimer() being set to TRUE should cause the reume from hibernation).
When I manual start the PC, the timer has expired. Is there something that I'm not doing ? (Tested on Win2000 Pro only, as this will be the only target system)
Doug
|
|
|
|
|
Perhaps, I should have emphasised the question in my mind - "Do I have to do anything within the OS (Win2K) to allow the wakeup to occur" ?
Doug
|
|
|
|
|
Hi,
I am working on a Clipboard saver program but...
after a window is closed OnDrawClipboard activates again.
This make my program to save another copy of last stored data in the memory...
Please help me...
Every new thing you learn,Gives you a new personality.
|
|
|
|
|
Hi
I'm using Tapi to send data by telephone line. I connect successfully and disconnect too but when I want to reconnect it . It can't initialize successfully and connection fails and I should exit program and run it again.
Agh
|
|
|
|
|
Ok, everything was going great until I added a Tab Control to a dlgbox. Now I'm lost or maybe confussed. I'm trying to add other controls like groupboxes, checkboxes and so on, on different tabs. Can someone please look at my code and see what I need to add so that a groupbox will show on a tab.
<br />
<br />
<br />
BOOL CALLBACK SigRoom (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)<br />
{<br />
INITCOMMONCONTROLSEX InitCtrlEx;<br />
InitCtrlEx.dwSize = sizeof(INITCOMMONCONTROLSEX);<br />
InitCtrlEx.dwICC = ICC_TAB_CLASSES;<br />
<br />
InitCommonControlsEx(&InitCtrlEx);<br />
TCITEM General, Finishes, Materials, Doors, Drawers, Hardware, CounterTop ;<br />
switch (message)<br />
{<br />
case WM_INITDIALOG:<br />
{<br />
<br />
General.mask = TCIF_TEXT;<br />
General.pszText = "General Info";<br />
General.cchTextMax = strlen("General") + 1;<br />
General.iImage = -1;<br />
General.lParam = 0;<br />
Finishes.mask = TCIF_TEXT;<br />
Finishes.pszText = "Finishes";<br />
Finishes.cchTextMax = strlen("Finishes") + 1;<br />
Finishes.iImage = -1;<br />
Finishes.lParam = 0;<br />
Materials.mask = TCIF_TEXT;<br />
Materials.pszText = "Materials";<br />
Materials.cchTextMax = strlen("Materials") + 1;<br />
Materials.iImage = -1;<br />
Materials.lParam = 0;<br />
Doors.mask = TCIF_TEXT;<br />
Doors.pszText = "Doors";<br />
Doors.cchTextMax = strlen("Doors") + 1;<br />
Doors.iImage = -1;<br />
Doors.lParam = 0;<br />
Drawers.mask = TCIF_TEXT;<br />
Drawers.pszText = "Drawers";<br />
Drawers.cchTextMax = strlen("Drawers") + 1;<br />
Drawers.iImage = -1;<br />
Drawers.lParam = 0;<br />
Hardware.mask = TCIF_TEXT;<br />
Hardware.pszText = "Hardware";<br />
Hardware.cchTextMax = strlen("Hardware") + 1;<br />
Hardware.iImage = -1;<br />
Hardware.lParam = 0;<br />
CounterTop.mask = TCIF_TEXT;<br />
CounterTop.pszText = "CounterTop";<br />
CounterTop.cchTextMax = strlen("CounterTop") + 1;<br />
CounterTop.iImage = -1;<br />
CounterTop.lParam = 0;<br />
<br />
TabCtrl_InsertItem(GetDlgItem(hDlg , IDC_TAB1), 0, &General);<br />
TabCtrl_InsertItem(GetDlgItem(hDlg , IDC_TAB1), 1, &Finishes);<br />
TabCtrl_InsertItem(GetDlgItem(hDlg , IDC_TAB1), 2, &Materials);<br />
TabCtrl_InsertItem(GetDlgItem(hDlg , IDC_TAB1), 3, &Doors);<br />
TabCtrl_InsertItem(GetDlgItem(hDlg , IDC_TAB1), 4, &Drawers);<br />
TabCtrl_InsertItem(GetDlgItem(hDlg , IDC_TAB1), 5, &Hardware);<br />
TabCtrl_InsertItem(GetDlgItem(hDlg , IDC_TAB1), 6, &CounterTop);<br />
return TRUE;<br />
break;<br />
}<br />
default:<br />
return FALSE;<br />
case WM_COMMAND:<br />
switch (LOWORD (wParam))<br />
{<br />
case IDOK:<br />
case IDCANCEL:<br />
EndDialog (hDlg, 0);<br />
return TRUE;<br />
}<br />
break;<br />
}<br />
}<br />
<br />
|
|
|
|
|
Typically a window is created for each tab.
In response to the TCN_SELCHANGE notification, you can bring the appropriate window
to the foreground (or perhaps show a hidden window, hiding the previous tab window).
To help size/position the windows in the tab's "client area", the TCM_ADJUSTRECT can
help.
See Tab Controls[^] for more details.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
You only have to call InitCommonControlsEx() once, not every time the window proc gets called.
Always zero-init your structs.
Always check return values.
|
|
|
|
|
In regards to what Mr. Dunn stated, here is how to zero init your structures in case you haven't seen it before in a code example...
INITCOMMONCONTROLSEX InitCtrlEx={0};
|
|
|
|
|
Printing in MFC seems so tricky to do...Right now I'm working on a notepad like program and the print function in it. I haven't been working on the function for a few months already. Seems like I forgot what everything does in it. But the problem I'm having now is I can't get the number of pages to print.
I copied this off some site:
CDC printerDC;
printerDC.Attach (printpage.GetPrinterDC ());
DOCINFO di;
::ZeroMemory (&di, sizeof (DOCINFO));
di.cbSize = sizeof (DOCINFO);
di.lpszDocName = filename;
printerDC.SetMapMode (MM_LOENGLISH);
CPrintInfo docInfo;
docInfo.SetMinPage(docInfo.GetMinPage());
docInfo.SetMaxPage(docInfo.GetMaxPage());
and it doesn't work at all. Anyone have any pointers as to how I can get the minpage and maxpage values? And also can anyone explain the functions for printing? I'm still a bit confused...
Edit: I found some great code on the internet, now all I need is some function to get the number of lines in my editbox...Is that any better than the number of pages?
-- modified at 21:59 Friday 3rd August, 2007
|
|
|
|
|
You can use your OnDraw() functions to print with if you stand on your head just right. Start an MFC (Visual C++ 6.0) Doc/View app deriving from CScrollView. Add the necessary code sections below using the ClassWizard and make sure they resemble the code below. The demo shows how to use the OnDraw for both drawing in a view and to the printer. It uses an arbitrary world coordinate system with MM_ISOTROPIC. It demonstrates how to let the OnDraw know which page is being displayed or printed so OnDraw can adapt it's drawing accordingly. It will fit the drawing to the output device while preserving the documents aspect ratio. I left the centering of the drawing in the device as an exercise for you. (Hint, center/align the viewport and the window with respect to each other).
I also did not reset the m_nPage after printing, error checking etc...
Let me know if I forgot something.
Hope this helps!
//CDocument members...
// Header file .h
protected:
CSize m_DocSize;
// Implementation file .cpp
CSize CYourDoc::GetDocSize() const
{
return m_DocSize;
}
CYourDoc::CYourDoc()
{
// TODO: add one-time construction code here
m_DocSize=CSize(2000,2800);
}
//CScrollView members...
// Header file .h
private:
int m_nPage;
// Implementation file .cpp
CYourView::CYourView()
{
// TODO: add construction code here
SetScrollSizes(MM_TEXT,CSize(0,0)); // Set arbitrary values
m_nPage=1;
}
/***************************************
NOTE: The pInfo parameter is uncommented
****************************************/
void CYourView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* pInfo)
{
// TODO: add extra initialization before printing
pInfo->SetMaxPage(3);
}
void CYourView::OnPrint(CDC* pDC, CPrintInfo* pInfo)
{
// TODO: Add your specialized code here and/or call the base class
m_nPage=pInfo->m_nCurPage;
CScrollView::OnPrint(pDC, pInfo);
}
void CYourView::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo)
{
CScrollView::OnPrepareDC(pDC);
// TODO: Add your specialized code here and/or call the base class
// Set up the DC for the current scale factor
int nExtentX;
int nExtentY;
CSize sizeDoc;
CRect rectClient;
pDC->SetMapMode(MM_ISOTROPIC); // Allow scaling with aspect ratio preserved
// Get pertinent rectangle data
GetClientRect(&rectClient);
sizeDoc=GetDocument()->GetDocSize();
sizeDoc.cy=(-sizeDoc.cy); // Y goes down as it increments
pDC->SetWindowExt(sizeDoc); // Window extent is size of document
// Calculate viewport extent
nExtentX=rectClient.Width();
nExtentY=(int)((nExtentX*sizeDoc.cy)/(sizeDoc.cx));
// What kind of device context do we have?
if (pDC->IsPrinting()==TRUE) {
pDC->SetViewportExt(pDC->GetDeviceCaps(HORZRES),-pDC->GetDeviceCaps(VERTRES));
} else {
// Context is for screen
pDC->SetViewportExt(nExtentX,nExtentY);
}
}
void CYourView::ResetScrollBars()
{
CSize sizeDoc;
CClientDC dc(this);
this->OnPrepareDC(&dc); // Update the device context
sizeDoc=GetDocument()->GetDocSize();
dc.LPtoDP(&sizeDoc); // Logical to device
this->SetScrollSizes(MM_TEXT,sizeDoc); // Update scrollbars
}
void CYourView::OnSize(UINT nType, int cx, int cy)
{
CScrollView::OnSize(nType, cx, cy);
// TODO: Add your message handler code here
ResetScrollBars();
}
void CYourView::OnDraw(CDC* pDC)
{
CTestPrintDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
CSize sizeDoc=pDoc->GetDocSize();
CRect rectOutline(0,0,sizeDoc.cx,sizeDoc.cy);
rectOutline.DeflateRect(10,10); // Ensure we can see it
LOGFONT logFont={0};
memcpy(logFont.lfFaceName,"Arial",6);
logFont.lfHeight=300;
CFont font;
font.CreateFontIndirect(&logFont);
CFont* pOldFont=pDC->SelectObject(&font);
CBrush* pOldBrush=(CBrush*)pDC->SelectStockObject(NULL_BRUSH);
CString sMessage;
sMessage.Format("You can add code to center the printout later\nPage %d",m_nPage);
pDC->DrawText(sMessage,&rectOutline,DT_CENTER|DT_WORDBREAK);
pDC->Rectangle(&rectOutline);
pDC->SelectObject(pOldFont);
pDC->SelectObject(pOldBrush);
}
|
|
|
|
|
Ehhh...I'm new at MFC...and I think my original post wasn't very clear. What I need right now is a way to get the number of lines a user types into a CEdit editbox, not a preview and a bunch of other things that look like scrollbar stuff...I already have a pretty good class for printing I got off the net. Just need the number of lines in a CEdit editbox.
|
|
|
|
|
I apologize if that code doesn't help. I had thought you asked for an explanation of how printing and pages work in MFC. A picture paints a thousand words so I thought a little working demo would help explain the paging mechanism in MFC.
Sorry for the misunderstanding.
|
|
|
|
|
No, it's ok. I did ask for an explanation of printing in MFC, and your code shows that pretty well but it doesn't do what I need. Thanks anyway. I get the idea of printing now.
|
|
|
|
|
In regards to your modified post, if you desire to calculate how many pages it will take to print your document, then you need to calculate some metrics to figure that out.
I think I misunderstood your original post. Are you using CEditView for your view class or a CScrollView? If your using CEditView, you really don't need to do anything as it is a mini pre-wrapped Notepad application and will print as is.
|
|
|
|
|
If I remember correctly, CEditView and CScrollView are used for previewing...? I hardly ever use them, not too familiar. What I'm doing here is I'm getting a CString of all the text in the editbox (CEdit), then printing the CString line by line in a loop. That's why I need the number of lines . I'm not using CEditView or CScrollView here.
|
|
|
|
|