|
Hi Dale,
I have confirmed the behavior you are describing. I am now getting the same results. I do not know if this behavior is by design.
However do you really need the "Peep &Help" to have a menu handler? If you give this menu item an ID of zero it will be ommitted from the customization dialog.
Best Wishes,
-David Delaune
|
|
|
|
|
I have some problems getting the screen coordinates of the client area of my mainframe and later increasing if the right side coordinate of the mainframes client Rect is smaller than the views right side coordinate.
For testing i positioned the view fitting in the mainframes client area(By Mouse). So the outside coordintes of the View Window should be the same as the inside coordinates of the main frame client area.
But it isn't!!
What am I doing wrong?
Code inside the view class:
GetWindowRect(ViewWindo wRectSC);
pMainFrame->GetClientRect(MainFrameClientRectCCMain);
MainFrameClientRectSC=MainFrameClientRectCCMain;
pMainFrame->ClientToScreen(MainFrameClientRectSC);
But
ViewWindowRectSC.right is not MainFrameClientRectSC.right
f.e.
ViewWindowRectSC: {top=99 bottom=918 left=14 right=1267}
MainFrameClientRectSC {top=42 bottom=964 left=4 right=1277}
I tried a lot but it is getting more and more unclear.
For example i tried to find frames or bars or something else with the GetSystemMetrics() function because i was thinking that there could be coordinate values not bringing these into account these. Didn't help.
Also tried to calculate the outside of the view window by first using
GetClientRect(ViewClientRectCC) and then
AdjustWindowRectEx(ViewClientRectCC,GetStyle(),1,GetExStyle());
Didn't help.
Thanks a lot
Hubert
[solved]
modified on Wednesday, November 11, 2009 4:29 AM
|
|
|
|
|
If your view is going to be bigger than the frame size, you must ideally use CScrollView so that the view is scrollable and you can also use CScrollView::ResizeParentToFit[^] to resize the frame to the size of the view.
|
|
|
|
|
Thanks for your answer.
I just reduced the problem to the described upstract conditions. In real i am setting views to before stored positions when i rebuild the application or the user opens a config file. The user is able to load a defined graphview which has coordinates which sometimes d'ont fit into the frame. (If the frame was smaller during constructing of the graphviews)
The use of scrollviews would be possible but i wouldn't like to have scrollbars. I constructed tabs in this view and in each tab there are one or more graphs. But there are also more then one view in the mainframe. The user has to positioned them once and he and others can open these configuration from file.
How does CScrollView::ResizeParentToFit increase the Mainframe? Just at the view coordinates which are bigger then the accordant one of the MainFrame?
Hubert
|
|
|
|
|
My own answer to my own question. A little stupid but maybe someone can use my solution to save some times and delivers new idears.
I solved my problem as follows:
First i used the sysinternals freeware zoom tool (http://technet.microsoft.com/de-de/sysinternals/bb897434%28en-us%29.aspx[^])to find the sizes of frames and borders.
Then the second tool the winspector tool from gipsysoft (http://www.windows-spy.com/[^] )to find out coordinates and classes of the interesting frames.
With this informations i was looking for parent() parent()....... frames and windows until i found the windows and frames with the correct coordinates.
The resulting code as follows:
CRect MainFrameClientRect,MainFrameClientRectSC,ViewsFrameWindowRect,PPWindowRectSC;
CWnd* PP;
PP=GetParent()->GetParent();
PP->GetClientRect(MainFrameClientRect);
MainFrameClientRectSC=MainFrameClientRect;
PP->ClientToScreen(MainFrameClientRectSC);
GetParentFrame()->GetWindowRect(ViewsFrameWindowRect);
CMainFrame* pMainFrame=(CMainFrame* )theApp.GetMainWnd();
WINDOWPLACEMENT MainFramePlacement;
MainFramePlacement.length = sizeof(WINDOWPLACEMENT);
::GetWindowPlacement(pMainFrame->m_hWnd,&MainFramePlacement);
if(ViewsFrameWindowRect.right>MainFrameClientRectSC.right)
MainFramePlacement.rcNormalPosition.right+=ViewsFrameWindowRect.right-MainFrameClientRectSC.right;
if(ViewsFrameWindowRect.bottom>MainFrameClientRectSC.bottom)
MainFramePlacement.rcNormalPosition.bottom+=ViewsFrameWindowRect.bottom-MainFrameClientRectSC.bottom;
pMainFrame->SetWindowPos(NULL,
MainFramePlacement.rcNormalPosition.left,
MainFramePlacement.rcNormalPosition.top,
MainFramePlacement.rcNormalPosition.right-MainFramePlacement.rcNormalPosition.left,
MainFramePlacement.rcNormalPosition.bottom-MainFramePlacement.rcNormalPosition.top,
SWP_NOZORDER);
pMainFrame->ShowWindow(theApp.m_nCmdShow);
pMainFrame->UpdateWindow();
Thanks to all which were looking at my question and thinking about a solution but couldn't help.
|
|
|
|
|
Hi,
I am trying to develop a console application, in which i am creating a new process (executable is c:\windows\system32\cmd.exe).
I am able to see the newly created process cmd.exe (console windows). but how can i execute some commands in the newly created console window programatically?
if( !CreateProcess("C:\\windows\\system32\\cmd.exe",
NULL, // Command line.
NULL, // Process handle not inheritable.
NULL, // Thread handle not inheritable.
FALSE, // Set handle inheritance to FALSE.
CREATE_NEW_CONSOLE, // No creation flags.
NULL, // Use parent's environment block.
NULL, // Use parent's starting directory.
&si, // Pointer to STARTUPINFO structure.
&pi ) // Pointer to PROCESS_INFORMATION structure.
)
{
printf( "CreateProcess failed (%d).\n", GetLastError() );
return;
}
|
|
|
|
|
The second parameter in the CreateProcess Function[^] is the commandline. You can pass your arguments there such as the path to a batch file. This is probably what your looking for.
If you are looking to do some advanced interaction with the console then it would be possible to overide the hStdInput handle of the STARTUPINFO Structure[^] with a handle to a named pipe or something.
Best Wishes,
-David Delaune
|
|
|
|
|
Hi David,
I think the second argument is the command line argument to the process that we are creating. i want to execute a command after creating the cmd.exe process.
for example, how can i execute a "DIR" command once i create a cmd.exe process? can i use WriteConsole() to execute the command?
Thanks in advance...
--Dev
|
|
|
|
|
devgo wrote: for example, how can i execute a "DIR" command once i create a cmd.exe process?
You mean like:
CreateProcess(NULL, "cmd.exe /c dir", NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); Using Randor's second suggestion will also work but is more involved.
"Old age is like a bank account. You withdraw later in life what you have deposited along the way." - Unknown
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
|
|
|
|
|
|
Hi David,
I am not looking to write something by WriteConsole()and not looking to redirect one screen out put to the other
i am looking to execute a command once the cmd.exe process has started. how can i do this?
Thanks,
Dev.
|
|
|
|
|
Hi Dev.
I suggest that you research and seek to understand STDIN STDOUT STDERR[^] because when you open a command prompt and you type DIR you are actually writing to the STDIN stream. After you research these streams you will have a better understanding of my answer.
devgo wrote: i am looking to execute a command once the cmd.exe process has started. how can i do this?
You have been given several options.
Option 1.) Pass a command on the CreateProcess command line.
>cmd /?
/C Carries out the command specified by string and then terminates
/K Carries out the command specified by string but remains
Option 2.) Interact with the standard input handle and pass commands.
How to spawn console processes with redirected standard handles[^]
These are your best options if you are using CreateProcess to open the command prompt as you described in your original post.
Here is another Microsoft sample of redirecting the input/output handles.
Creating a Child Process with Redirected Input and Output[^]
Best Wishes,
-David Delaune
|
|
|
|
|
Hi David,
Thank you very much for your help. i got the work done with option 1). i am a new bee for windows. i will look for the option 2) as well.
Thanks for your inputs.
--Dev
|
|
|
|
|
Hi David,
As you were aware, i am trying to execute a command in the console window created through createprocess(); now i am trying to execute the command by using Pipes as you suggested.
I am pasting the code here. i am not able to print the string on the console window created. could you please suggest what i am doing wrong.
/********************************CODE ******************************* /
void main()
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
DWORD i;
HANDLE hout;
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pi, sizeof(pi) );
HWND hWnd = NULL;
TCHAR buf[128];
HANDLE g_hChildStd_IN_Rd = NULL;
HANDLE g_hChildStd_IN_Wr = NULL;
HANDLE g_hChildStd_OUT_Rd = NULL;
HANDLE g_hChildStd_OUT_Wr = NULL;
SECURITY_ATTRIBUTES saAttr;
DWORD dwRead, dwWritten;
CHAR chBuf[128];
BOOL bSuccess = FALSE;
// Set the bInheritHandle flag so pipe handles are inherited.
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
// Create a pipe for the child process's STDOUT.
if ( ! CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &saAttr, 0) )
printf("StdoutRd CreatePipe");
// Ensure the read handle to the pipe for STDOUT is not inherited.
if ( ! SetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0) )
printf("Stdout SetHandleInformation");
// Create a pipe for the child process's STDIN.
si.hStdError = g_hChildStd_OUT_Wr;
si.hStdOutput = g_hChildStd_OUT_Wr;
si.hStdInput = g_hChildStd_OUT_Rd;
//si.dwFlags |= STARTF_USESTDHANDLES;
// Start the child process.
if( !CreateProcess("C:\\windows\\system32\\cmd.exe", // No module name (use command line).
NULL,//// Command line.
NULL, // Process handle not inheritable.
NULL, // Thread handle not inheritable.
FALSE, // Set handle inheritance to FALSE.
CREATE_NEW_CONSOLE, // No creation flags.
NULL, // Use parent's environment block.
NULL, // Use parent's starting directory.
&si, // Pointer to STARTUPINFO structure.
&pi ) // Pointer to PROCESS_INFORMATION structure.
)
{
printf( "CreateProcess failed (%d).\n", GetLastError() );
return;
}
bSuccess = WriteConsole(g_hChildStd_OUT_Rd, "dir", 3, &dwWritten, NULL);
CloseHandle(g_hChildStd_OUT_Rd);
/***********************************************************************************/
|
|
|
|
|
 Hi Devgo,
In the future you should not reply to yourself. You are lucky that I review my old threads... I did not get notification of your response because you replied to yourself. Anyway I wrote a quick and dirty sample for you. In this example I am creating an instance of CMD.EXE and writind the Dir command to its STDIN pipe. I then use MessageBox to show the results.
#include "stdafx.h"
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <process.h>
#pragma comment(lib,"user32.lib")
HANDLE g_hChildStd_IN_Rd = NULL;
HANDLE g_hChildStd_IN_Wr = NULL;
HANDLE g_hChildStd_OUT_Rd = NULL;
HANDLE g_hChildStd_OUT_Wr = NULL;
unsigned __stdcall ReadCMDThread(void* pArguments)
{
DWORD dwAvailable =0;
DWORD bytesRead =0;
CHAR szOut[4096] = {0};
while(0 == bytesRead)
{
PeekNamedPipe(g_hChildStd_OUT_Rd,szOut,sizeof(szOut),&bytesRead,&dwAvailable,NULL);
if(0 != bytesRead)
{
Sleep(1000);
ReadFile(g_hChildStd_OUT_Rd,szOut,sizeof(szOut),&bytesRead,NULL);
::MessageBoxA(NULL,szOut,"",MB_OK);
break;
}
}
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
DWORD bytesRead;
DWORD exitcode;
PROCESS_INFORMATION pi;
STARTUPINFO si;
SECURITY_ATTRIBUTES sa;
ZeroMemory(&sa,sizeof(sa));
sa.nLength=sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle=TRUE;
CreatePipe(&g_hChildStd_IN_Rd,&g_hChildStd_IN_Wr,&sa,0);
CreatePipe(&g_hChildStd_OUT_Rd,&g_hChildStd_OUT_Wr,&sa,0);
ZeroMemory(&si,sizeof(si));
GetStartupInfo(&si);
si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
si.hStdOutput = g_hChildStd_OUT_Wr;
si.hStdError = g_hChildStd_OUT_Wr;
si.hStdInput = g_hChildStd_IN_Rd;
si.wShowWindow = SW_HIDE;
BOOL bSuccess = CreateProcess(
_T("C:\\windows\\system32\\cmd.exe"),
NULL,
NULL,
NULL,
TRUE,
CREATE_NEW_CONSOLE,
NULL,
NULL,
&si,
&pi);
UINT threadID;
HANDLE hThread = (HANDLE)_beginthreadex(NULL,0,&ReadCMDThread,NULL,0,&threadID);
Sleep(500);
if(INVALID_HANDLE_VALUE != hThread)
{
DWORD dwWritten = 0;
CHAR szIN[4096];
strcpy(szIN,"dir\n");
WriteFile(g_hChildStd_IN_Wr,szIN,strlen(szIN),&dwWritten,NULL);
WaitForSingleObject(hThread,INFINITE);
CloseHandle(hThread);
strcpy(szIN,"exit\n");
WriteFile(g_hChildStd_IN_Wr,szIN,strlen(szIN),&dwWritten,NULL);
}
CloseHandle(g_hChildStd_IN_Rd);
CloseHandle(g_hChildStd_IN_Wr);
CloseHandle(g_hChildStd_OUT_Rd);
CloseHandle(g_hChildStd_OUT_Wr);
return 0;
}
The code is ugly and contains some Sleeps to allow CMD.EXE to initialize. I also use Sleep to wait for the Read pipe to become full. There are probably better ways to do this. Also... on my Windows7 workstation I had problems terminating CMD.exe by closing its handles. Using TerminateProcess is generally not desirable so I opted to write exit to the STDIN stream.
There are some other functions that you might want to get familiar with:
WriteConsoleInput Function[^]
GenerateConsoleCtrlEvent Function[^]
Good Luck,
-David Delaune
|
|
|
|
|
I want to use different activeX files (for instance release/debug) versions and to do so i need to register the activeX according to realtive path (installation will be in different places).
Is there a way to do so, so that both version work?
Thanks,
Eyal
|
|
|
|
|
when you register an ActiveX object, its CLSID is added to HKEY_CLASSES_ROOT/CLSID and a path to the DLL is added below that. so if the debug and release versions use the same CLSIDs for their interfaces (which they typically do), there's no way to have multiple versions, regardless of where the DLLs live.
|
|
|
|
|
Greetings!
We have just started working in VS 2008. Our code, written in C++, often stores SQL select statements in string variables. These strings are often longer than the debugger can display. Is there a way to copy the entire string onto the clipboard so I can paste it into Notepad or an SQL command window or some such thing?
Thank you very much!
RobR
|
|
|
|
|
Use your right mouse button to click on the value, then select "copy value"
|
|
|
|
|
there's usually a little magnifying glass next to the short string display, in the debugger watch windows. clicking that will bring up a window (the "visualizer") with the full text.
|
|
|
|
|
Hi. Well.. I need to add some tooltips to my main window (CDialog).
So... I do this in OnInit
bool test21=TTC.Create(this);
theApp.tooltip=&(TTC);
m_but.MoveWindow(0,0,500,500);
bool test11=theApp.tooltip->AddTool(m_but,"Cool?");
TTC.Activate(TRUE);
and
BOOL MainDial::PreTranslateMessage(MSG* pMsg)
{
if (NULL != theApp.tooltip)
theApp.tooltip->RelayEvent(pMsg);
return CDialog::PreTranslateMessage(pMsg);
}
Appears a great button, but hint doesn't. Why? Any idea? Smthng that i'am missing? Huh?
|
|
|
|
|
Could it be that in your OnInitDialog the TTC variable, which is i assume a CToolTipCtrl a local variable? If so then when your OnInitDialog is done and returns, TTC will be deleted and its destructor also destroys the tooltip. Of course that you don't get a crash in PreTranslateMessage suggests this is not the case but it might happen. Try making your TTC a member of the dialog class if it is not and use that instance instead of storing a pointer at it.
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> Sometimes you just have to hate coding to do it well. <
|
|
|
|
|
Well.. My CToolTipCtrl is member of MainDial of course. And by the way i already made it work with this button, but now i have another trouble. I create lots of dynamic buttons, inside of MPictureBox.Create i write:
BOOL result = CButton::Create(lpszCaption,dwStyle,rect,pParentWnd,nID);
this->SetParent(pParentWnd);
theApp.tooltip->AddTool(this,"HM?!");
but once again it doesn't help. Hint doesn't appear. Any idea?
|
|
|
|
|
You probably need to relay messages received by your picture box also to the tooltip control not only ones targeted at your dialog box. Aside of that, no idea. Just out of curiosity, what was your first problem?
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> Sometimes you just have to hate coding to do it well. <
|
|
|
|
|
My original problem was to make some sort of game. Jackal. It's a board game invented 30-40 years ago at MGU (principal university of Moscow). For now i made it, but it's possible to play it only for humans against humans on the same cpu (hot seat mode). (Later i plan to make net support and cpu gamers). If you want to see what i have done for now drop.io/shchepin/ release.rar (requires redistributable package for vs2008 sp1).
P.S. I intented with
BOOL MPictureBox::PreTranslateMessage(MSG* pMsg)
{
if (NULL != theApp.tooltip)
theApp.tooltip->RelayEvent(pMsg);
return CButton::PreTranslateMessage(pMsg);
}
Didn't helped... =(
|
|
|
|
|