|
Calling OnNcPaint() directly won't work; you must let the system call it so that you know it has invalidated the right area. I'm not sure why it doesn't call your OnNcPaint() handler when going inactive; I suspect it is a bit of a loophole in the MFC framework whereby it doesn't behave consistently.
Perhaps if you tell us why you are trying to paint in this area, we can suggest an alternative approach? Trying to override the system is always erratic at best {:v)
|
|
|
|
|
I want to change the height of the title bar of a dialog.But I don't know how to do.
Thanks.
|
|
|
|
|
|
But I don't know the right step.
Thanks
|
|
|
|
|
Overide the WM_NCCALSIZE, and in the OnNcCalcSize() function, you will get rect of the dialog
pstncsp->rgrc[0]
And that rect contains you present client area. So if you wanne increase the nonclient area, decrease the client area. Say in your case you want to increase the no client area on the top. For that do do as follows..
void MyDlg::OnNcCalcSize( BOOL bCalcValidRects, NCCALCSIZE_PARAMS FAR* pstncsp )
{
CDialog::OnNcCalcSize( bCalcValidRects_i, pstncsp_i );
pstncsp_i->rgrc[0].top += 50;// Increases the non client area by 50
}
|
|
|
|
|
It works well now,Thank you very much.
|
|
|
|
|
Hi everybody,
my application opens some processes via CreateProcess()
If the application is aborted hardly ( over TaskManager ) the
child processes are still running.
Is there a possibility to start the child processes and if there parent is dead,
they will also stop to exist?
Big thanks for help
|
|
|
|
|
Pass the process HANDLE of the parent to the child. Make sure this HANDLE is inheritable and the bInheritHandles argument in your CreateProcess call is set to TRUE . Then the child can use the WaitForSingleObject function to detect if the child parent is dead (and, as its name suggests, wait for this to happen).
-- modified at 20:49 Monday 10th September, 2007
Steve
|
|
|
|
|
Thanks for help
It's more the problem if the Parent-Process dies and the child processes are still living.
If the parent process ( the GUI ) creates 5 new child processes and the windows user kills the
parent process with the TaskManager, so there are still 5 processes running and never be closed.
That's the problem
|
|
|
|
|
The procedure I outlined will do exactly what you want. Here's an example:
-----------------------------------------------
// ParentChild.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <Windows.h>
#include <conio.h>
#include <string>
#include <sstream>
#include <algorithm>
#include <memory>
#include <assert.h>
using namespace std;
HANDLE GetInheritableProcessHandle()
{
HANDLE hProcess;
BOOL bOK = DuplicateHandle(
GetCurrentProcess(), // HANDLE hSourceProcessHandle
GetCurrentProcess(), // HANDLE hSourceHandle
GetCurrentProcess(), // HANDLE hTargetProcessHandle
&hProcess, // LPHANDLE lpTargetHandle
SYNCHRONIZE, // DWORD dwDesiredAccess
TRUE, // BOOL bInheritHandle
0 // DWORD dwOptions
);
if (!bOK)
{
return NULL;
}
return hProcess;
}
void SpawnChild()
{
// Get our path.
char Us[MAX_PATH];
GetModuleFileName(NULL, Us, sizeof(Us));
// Get an inheritable process handle for this process.
HANDLE hUs = GetInheritableProcessHandle();
assert(hUs!=NULL);
// Build the command line.
ostringstream oss;
oss << "\"" << Us << "\" " << reinterpret_cast<DWORD>(hUs);
string CommandLine = oss.str();
// Build a mutable version of the command line string.
char *pMutable = new char[CommandLine.length()+1];
const char *pStr = CommandLine.c_str();
memcpy(pMutable, pStr, CommandLine.length()+1);
// Launch the child process.
STARTUPINFO si = {0};
si.cb = sizeof(si);
si.lpTitle = "I am the child!";
PROCESS_INFORMATION pi;
BOOL bOK = CreateProcess(
NULL, // LPCTSTR lpApplicationName
pMutable, // LPTSTR lpCommandLine
NULL, // LPSECURITY_ATTRIBUTES lpProcessAttributes
NULL, // LPSECURITY_ATTRIBUTES lpThreadAttributes
TRUE, // BOOL bInheritHandles
CREATE_NEW_CONSOLE, // DWORD dwCreationFlags
NULL, // LPVOID lpEnvironment
NULL, // LPCTSTR lpCurrentDirectory
&si, // LPSTARTUPINFO lpStartupInfo
&pi // LPPROCESS_INFORMATION lpProcessInformation
);
delete [] pMutable; // Free the memory.
CloseHandle(hUs);
if (!bOK)
{
return;
}
// As always, close handles you don't need or are finished with!
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
int main(int argc, char* argv[])
{
if (argc==1)
{
cout << "I am the parent." << endl;
SpawnChild();
cout << "Press any key to exit." << endl;
_getch();
}
else
{
cout << "I am the child." << endl;
// Get the handle to the parent from the command line.
DWORD HandleValue;
istringstream iss(argv[1]);
iss >> HandleValue;
HANDLE hParent = reinterpret_cast<HANDLE>(HandleValue);
// Wait for the parent to exit or be killed.
WaitForSingleObject(hParent, INFINITE);
// Close handles you're finished with.
CloseHandle(hParent);
}
return 0;
}
Steve
|
|
|
|
|
Ok, i see, it kills really the child processes.
But how does it work exactly?
The command, here pMutable, stores the path & exe and a specific number ( dublicated handler ) after it.
Does the child process also die because the dublicated handle is destroyed and the clone-handle
can't no longer exists and kills that way the child process?
Big thanks for you help !!
|
|
|
|
|
The child process isn’t killed; it’s waiting for the parent process to finish (either gracefully of forcefully). A process HANDLE is a waitable object -- it becomes signaled when the process it identifies no longer exists. WaitForSingleObject waits for a waitable object to become signaled. All the DuplicateHandle stuff is to make the HANDLE inheritable so it is inherited by the child (since the bInheritHandles argument passed to CreateProcess is TRUE ). The value passed in the command line is the duplicated HANDLE 's value.
Steve
|
|
|
|
|
Ok, i understand it now.
So i can create a thread which waits till the parent-process is dead and closes then the application.
Otherwise, if the child closes at first, i kill the Thread which waites on the handle.
Big thanks for your great help
|
|
|
|
|
That’s the basic idea. A word of warning: don’t use the TerminateThread function! See here[^] for details. A professional implementation would use the WaitForMultipleObjects function instead of WaitForSingleObject ; one of the objects is the parent's HANDLE and the other an event (see CreateEvent ) that you use to tell the thread to exit gracefully. Your main thread uses the event to signal the other thread to close down and then waits for it to do so using WaitForSingleObject on the thread's HANDLE .
Steve
|
|
|
|
|
Hello
It seems if you create a process in your application using createprocess or any other API and if the parent application gets terminated forcibly (as in your case) the child process will not get terminated. For referenc refer the "Terminating a Process" section of the MSDN. To go to this topic, look into the Remarks section of "CreateProcess" API.
In the "Terminating a Process" it is clearly mentioned as "When the system is terminating a process, it does not terminate any child processes that the process has created."
However in that section they have mentioned a possibility of achieving ur requirement of terminating a child process when the parent application gets terminated.
Thanx
|
|
|
|
|
Thanks for your help
The possibility offered by MSDN won't fix this kind of problem
So i think there is no possibility to work around my problem
|
|
|
|
|
baerten wrote: So i think there is no possibility to work around my problem
I wouldn't go that far. See here[^].
Steve
|
|
|
|
|
i am using dialog ,in that i have an edit control,when ever my dialog displays cursor must be in the edit control,plz help me............
|
|
|
|
|
You can call GotoDlgCtrl() API for that edit to set the focus. If it is in OnInitDialog, you should return FALSE.
- NS -
|
|
|
|
|
ok fine,if it in another function ,wts the processs............
|
|
|
|
|
GotoDlgCtrl itself...
- NS -
|
|
|
|
|
tried setting it to a member of CEdit(The edit box itself ) but GoToDlgCtrl is not a member of CEdit.
Wamuti: Any man can be an island, but islands to need water around them!
Edmund Burke: No one could make a greater mistake than he who did nothing because he could do only a little.
|
|
|
|
|
Wamuti wrote: tried setting it to a member of CEdit(The edit box itself )
No... You have to call like, GotoDlgCtrl( &m_edit );
- NS -
|
|
|
|
|
Set the "Tab stop" for the edit control as 1. For doing this click Ctrl+D on the resource view of the dialog. Set the edit control tab stop as 1. It is the simplest way to solve your problem.
Sreedhar DV
|
|
|
|
|
add a member variable for that edit box e.g. "m_deEditBox" using the class wizard and set the category as a control and the variable type should change to be automaticaly CEdit.
Wherever you want to receive focus use the SetFocus() and that should do the trick
e.g. :
m_deEditBox.SetFocus();
Only make sure m_deEditBox is visible within the class you are using!
Wamuti: Any man can be an island, but islands to need water around them!
Edmund Burke: No one could make a greater mistake than he who did nothing because he could do only a little.
|
|
|
|