|
Change the code like this:
PROCESS_INFORMATION pi[3];
STARTUPINFO si[3];
ZeroMemory( &si[0], sizeof(STARTUPINFO));<br />
si[0].cb = sizeof(STARTUPINFO); <br />
ZeroMemory( &pi[0], sizeof(PROCESS_INFORMATION)); <br />
ZeroMemory( &si[1], sizeof(STARTUPINFO));<br />
si[1].cb = sizeof(STARTUPINFO); <br />
ZeroMemory( &pi[1], sizeof(PROCESS_INFORMATION)); <br />
ZeroMemory( &si[2], sizeof(STARTUPINFO));<br />
si[2].cb = sizeof(STARTUPINFO); <br />
ZeroMemory( &pi[2], sizeof(PROCESS_INFORMATION));
Regards,
Andrzej Markowski
|
|
|
|
|
Thanks for the help Andrzej
I have configured the code as shown below: Including a couple of functions. The program builds with 0 errors and 0 warnings, but for some reason when I enter a choice like (1) for "Freecell", my program quits, the program that I have opened remains open, so I do not have the chance to quit the Freecell program. Not sure why it is not giving me another choice:
#include <iostream.h><br />
#include <windows.h><br />
#include <string.h><br />
#include <stdio.h><br />
<br />
void DisplayMenu();<br />
void process(int option);<br />
<br />
<br />
void main()<br />
{<br />
DisplayMenu();<br />
return;<br />
}<br />
<br />
void DisplayMenu()<br />
{<br />
int option;<br />
<br />
cout << "\n\n\n";<br />
cout << "\n\t*********************************";<br />
cout << "\n\t* *";<br />
cout << "\n\t* MENU *";<br />
cout << "\n\t* *";<br />
cout << "\n\t* 1. FreeCell *";<br />
cout << "\n\t* 2. MineSweeper *";<br />
cout << "\n\t* 3. Paint *";<br />
cout << "\n\t* 4. Quit *";<br />
cout << "\n\t* *";<br />
cout << "\n\t*********************************";<br />
<br />
cout << "\n\nPlease type your choice "<br />
<< "and press the return key : ";<br />
<br />
cin >> option;<br />
process(option);<br />
<br />
return;<br />
}<br />
<br />
void process(int option)<br />
{<br />
<br />
STARTUPINFO si[3];<br />
PROCESS_INFORMATION pi[3]; <br />
int i=0;<br />
<br />
ZeroMemory( &si[0], sizeof(si[0]) );<br />
si[0].cb = sizeof(si[0]); <br />
ZeroMemory( &pi[0], sizeof(pi[0]) ); <br />
<br />
ZeroMemory( &si[1], sizeof(si[1]) );<br />
si[1].cb = sizeof(si[1]); <br />
ZeroMemory( &pi[1], sizeof(pi[1]) ); <br />
<br />
ZeroMemory( &si[2], sizeof(si[2]) );<br />
si[2].cb = sizeof(si[2]); <br />
ZeroMemory( &pi[2], sizeof(pi[2]) ); <br />
<br />
switch (option)<br />
{<br />
case 1 : if(pi[0].hProcess==NULL)CreateProcess( NULL, <br />
"FreeCell.exe", <br />
NULL, <br />
NULL, <br />
FALSE, <br />
NULL, <br />
NULL, <br />
NULL, <br />
&si[0], <br />
&pi[0]); <br />
<br />
{<br />
ExitProcess(1);<br />
} <br />
<br />
<br />
system("cls");<br />
DisplayMenu();<br />
<br />
break; <br />
<br />
case 2 : if(pi[1].hProcess==NULL)CreateProcess( NULL, <br />
"winmine.exe", <br />
NULL, <br />
NULL, <br />
FALSE, <br />
NULL, <br />
NULL, <br />
NULL, <br />
&si[1], <br />
&pi[1]); <br />
<br />
{<br />
ExitProcess(1);<br />
} <br />
<br />
<br />
system("cls");<br />
DisplayMenu();<br />
<br />
break;<br />
<br />
case 3 : if(pi[2].hProcess==NULL)CreateProcess( NULL, <br />
"MsPaint.exe",
NULL, <br />
NULL, <br />
FALSE, <br />
NULL, <br />
NULL, <br />
NULL, <br />
&si[2], <br />
&pi[2]); <br />
<br />
{<br />
ExitProcess(1);<br />
} <br />
<br />
system("cls");<br />
DisplayMenu();<br />
<br />
break;<br />
<br />
<br />
<br />
case 4 : if(pi[0].hProcess)::PostThreadMessage(pi[0].dwThreadId,WM_QUIT,0,0);<br />
if(pi[1].hProcess)::PostThreadMessage(pi[1].dwThreadId,WM_QUIT,0,0);<br />
if(pi[2].hProcess)::PostThreadMessage(pi[2].dwThreadId,WM_QUIT,0,0);<br />
CloseHandle( pi[0].hProcess );<br />
CloseHandle( pi[0].hThread );<br />
CloseHandle( pi[1].hProcess );<br />
CloseHandle( pi[1].hThread );<br />
CloseHandle( pi[2].hProcess );<br />
CloseHandle( pi[2].hThread );<br />
exit(100);<br />
<br />
break;<br />
<br />
default : printf("\a\aOption Not Available\n");<br />
system("cls");<br />
DisplayMenu();<br />
}<br />
<br />
return;<br />
}
|
|
|
|
|
You should declare the arrays (si and pi ) as global variables. Also you can't call the DisplayMenu from within the process function (recursion).
Here's an example how to fix these problems:
STARTUPINFO si[3];
PROCESS_INFORMATION pi[3];
int DisplayMenu();
void process(int option);
void main()
{
ZeroMemory( &si[0], sizeof(si[0]) );
si[0].cb = sizeof(si[0]);
ZeroMemory( &pi[0], sizeof(pi[0]) );
ZeroMemory( &si[1], sizeof(si[1]) );
si[1].cb = sizeof(si[1]);
ZeroMemory( &pi[1], sizeof(pi[1]) );
ZeroMemory( &si[2], sizeof(si[2]) );
si[2].cb = sizeof(si[2]);
ZeroMemory( &pi[2], sizeof(pi[2]) );
while(DisplayMenu()!=4)
return;
}
int DisplayMenu()
{
int option;
system("cls");
cout << "\n\n\n";
cout << "\n\t*********************************";
cout << "\n\t* *";
cout << "\n\t* MENU *";
cout << "\n\t* *";
cout << "\n\t* 1. FreeCell *";
cout << "\n\t* 2. MineSweeper *";
cout << "\n\t* 3. Paint *";
cout << "\n\t* 4. Quit *";
cout << "\n\t* *";
cout << "\n\t*********************************";
cout << "\n\nPlease type your choice "
<< "and press the return key : ";
cin >> option;
process(option);
return option;
}
void process(int option)
{
switch (option)
{
case 1 : if(pi[0].hProcess==NULL)CreateProcess( NULL,
"FreeCell.exe",
NULL,
NULL,
FALSE,
NULL,
NULL,
NULL,
&si[0],
&pi[0]);
break;
case 2 : if(pi[1].hProcess==NULL)CreateProcess( NULL,
"winmine.exe",
NULL,
NULL,
FALSE,
NULL,
NULL,
NULL,
&si[1],
&pi[1]);
break;
case 3 : if(pi[2].hProcess==NULL)CreateProcess( NULL,
"MsPaint.exe",
NULL,
NULL,
FALSE,
NULL,
NULL,
NULL,
&si[2],
&pi[2]);
break;
case 4 : if(pi[0].hProcess)::PostThreadMessage(pi[0].dwThreadId,WM_QUIT,0,0);
if(pi[1].hProcess)::PostThreadMessage(pi[1].dwThreadId,WM_QUIT,0,0);
if(pi[2].hProcess)::PostThreadMessage(pi[2].dwThreadId,WM_QUIT,0,0);
CloseHandle( pi[0].hProcess );
CloseHandle( pi[0].hThread );
CloseHandle( pi[1].hProcess );
CloseHandle( pi[1].hThread );
CloseHandle( pi[2].hProcess );
CloseHandle( pi[2].hThread );
break;
default : printf("\a\aOption Not Available\n");
break;
}
return;
}
Regards,
Andrzej Markowski
|
|
|
|
|
Finally got it!
Thanks for all the help
|
|
|
|
|
Again thanks for the help Andrzej, I have pretty much configured the program to work how I want except for one thing.
I want to be able to open more than one of the same program. So if I open one Paint program I want to be able to enter 3 again for Paint and have it open another. It only lets me open one of each right now.
Is there anyway to work around it? Meaning can I keep the global variables or is that one of the things that is preventing me from opening more than one program?
Thanks again.
|
|
|
|
|
Just want to clarify something...
I know how to be able to open more than one program but I'm not sure how to let the computer keep track of them so it closes them all.
When I do change it to open more than one program and I enter 4 to close them it does not close any of them.
|
|
|
|
|
Your program has to save the ThreadId for each new created process. Later the ThreadId is passed as the parameter to the PostThreadMessage function which is called to close the program the user opened. The modified example saves this information in the rp array of RUNNING_PROCESS_INFO structures. The nRPCounter specifies a number of currently running processes and also is the next avaliable index in the rp table. When the process is created a space for the RUNNING_PROCESS_INFO structure is allocated at the and of the array and the nRPCounter is incremented. When the user closes the program the counter is decremented and the structures in the array located below deleted item are moved one item up.
#include stdio.h
#include process.h
#include iostream.h
#include time.h
#include windows.h
typedef struct
{
DWORD dwThreadId;
BYTE bProcessType;
} RUNNING_PROCESS_INFO;
#define MAX_PROCESSES 10
RUNNING_PROCESS_INFO rp[MAX_PROCESSES];
int nRPCounter = 0;
int DisplayMainMenu();
void DisplayStopProcessMenu();
void process(int option);
int main(int argc, char* argv[])
{
while(DisplayMainMenu()!=5);
return 0;
}
int DisplayMainMenu()
{
int option=0;
system("cls");
cout << "\n\n\n";
cout << "\n\t*********************************";
cout << "\n\t* *";
cout << "\n\t* MAIN MENU *";
cout << "\n\t* *";
cout << "\n\t* 1. FreeCell *";
cout << "\n\t* 2. MineSweeper *";
cout << "\n\t* 3. Paint *";
cout << "\n\t* 4. StopProcess *";
cout << "\n\t* 5. Quit *";
cout << "\n\t* *";
cout << "\n\t*********************************";
cout << "\n\nPlease type your choice "<< "and press the return key : ";
cin >> option;
process(option);
return option;
}
void DisplayStopProcessMenu()
{
int option=0;
system("cls");
cout << "\n\n\n";
cout << "\n\t*********************************";
cout << "\n\t* *";
cout << "\n\t* STOP PROCESS MENU *";
cout << "\n\t* *";
for(int i=0;i<nRPCounter;i++)
{
cout << "\n\t* ";
cout << i+1;
cout << ". ";
if(rp[i].bProcessType==1)
cout << "FreeCell *";
else if(rp[i].bProcessType==2)
cout << "MineSweeper *";
else
cout << "Paint *";
}
cout << "\n\t* *";
cout << "\n\t*********************************";
cout << "\n\nPlease type your choice "<< "and press the return key : ";
cin >> option;
if(option>=1 && option<=nRPCounter)
{
PostThreadMessage(rp[option-1].dwThreadId,WM_QUIT,0,0);
nRPCounter--;
for(int i=option-1; i<nRPCounter; i++)
memcpy(&rp[i],&rp[i+1],sizeof(RUNNING_PROCESS_INFO));
}
}
void process(int option)
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
if(option>=1 && option<=3)
{
if(nRPCounter==MAX_PROCESSES)
{
printf("\a\aRunning processes table full\n");
return;
}
ZeroMemory( &pi, sizeof(PROCESS_INFORMATION) );
ZeroMemory( &si, sizeof(STARTUPINFO) );
si.cb = sizeof(STARTUPINFO);
}
switch (option)
{
case 1 :
if(CreateProcess( NULL, "FreeCell.exe", NULL, NULL, FALSE, NULL, NULL, NULL, &si, &pi))
{
rp[nRPCounter].dwThreadId = pi.dwThreadId;
rp[nRPCounter++].bProcessType = 1;
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
}
else
printf("\a\aCreateProcess(...) failed\n");
break;
case 2 :
if(CreateProcess( NULL, "winmine.exe", NULL, NULL, FALSE, NULL, NULL, NULL, &si, &pi))
{
rp[nRPCounter].dwThreadId = pi.dwThreadId;
rp[nRPCounter++].bProcessType = 2;
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
}
else
printf("\a\aCreateProcess(...) failed\n");
break;
case 3 :
if(CreateProcess( NULL, "MsPaint.exe", NULL, NULL, FALSE, NULL, NULL, NULL, &si, &pi))
{
rp[nRPCounter].dwThreadId = pi.dwThreadId;
rp[nRPCounter++].bProcessType = 3;
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
}
else
printf("\a\aCreateProcess(...) failed\n");
break;
case 4:
DisplayStopProcessMenu();
break;
case 5 :
{
for(int i=0; i<nRPCounter;i++)
PostThreadMessage(rp[i].dwThreadId,WM_QUIT,0,0);
}
break;
default :
printf("\a\aOption Not Available\n");
break;
}
}
Regards,
Andrzej Markowski
|
|
|
|
|
Very Important!!!!
Don't use WM_QUIT message to kill other processes. Instead of WM_QUIT use WM_CLOSE. If you send WM_QUIT the application will not clean up resources and you will have memory leaks.
Regards,
Andrzej Markowski
|
|
|
|
|
Posting WM_CLOSE message to the main thread using PostThreadMessage doesn't close your application also. You have to post WM_CLOSE message to all windows on the main thread, as vikrams said. Here's the code how to do this :
BOOL CALLBACK EnumThreadWndProc(HWND hwnd, LPARAM lParam)
{
::PostMessage(hwnd,WM_CLOSE,0,0);
return TRUE;
}
EnumThreadWindows(rp[option-1].dwThreadId,EnumThreadWndProc,0); Regards,
Andrzej Markowski
|
|
|
|
|
I´m trying to use the IDirectDrawSurface::AlphaBlt method in wince.
Then I have to create an alpha surface and blit that surface to a "normal" (not an alpha surface) surface with the AlphaBlt method, I think....
But when I try to create an alpha surface,I get an invalid parameter as a result!
Is there anybody that has a clue to this error?
These are important flags for the DDPIXELFORMAT in wince:
DDPF_ALPHA: The pixel format describes an alpha-only surface.
DDPF_ALPHAPIXELS: The surface has alpha channel information in the pixel format.
DDPF_ALPHAPREMULT: The color components in the pixel are premultiplied by the alpha value in the pixel. If this flag is set, the DDPF_ALPHAPIXELS flag must also be set. If this flag is not set but the DDPF_ALPHAPIXELS flag is set, the color components in the pixel format are not premultiplied by alpha. In this case, the color components must be multiplied by the alpha value at the time that an alpha-blending operation is performed.
DDPF_RGB: The RGB data in the pixel format structure is valid.
I think I should only use the DDPF_ALPHA and DDPF_RGB flags but I am not sure?
Any comments?
I don´t think I should specify any alphabitdepth as there is no alpha channel information in the RGB_565 pixelformat,isn´t that right?
This is how the code looks like:
Globals:
<br />
LPDIRECTDRAW4 lpDD4;<br />
LPDIRECTDRAWSURFACE4 lpddsurf;<br />
SIZE size;<br />
<br />
size.cx=486;<br />
size.cy=274;<br />
<br />
CreateAlphaSurface(&lpddsurf,&size); <br />
<br />
int CreateAlphaSurface( LPDIRECTDRAWSURFACE4* lplpDDS,LPSIZE lpSize )<br />
{<br />
DDSURFACEDESC2 ddsd;<br />
HRESULT res;<br />
<br />
ZeroMemory( &ddsd, sizeof ddsd );<br />
ddsd.dwSize = sizeof ddsd;<br />
<br />
ddsd.dwFlags=DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT;<br />
<br />
ddsd.ddsCaps.dwCaps =DDSCAPS_ALPHA;<br />
ddsd.ddpfPixelFormat.dwRBitMask=0xf800;<br />
ddsd.ddpfPixelFormat.dwGBitMask=0x07e0;<br />
ddsd.ddpfPixelFormat.dwBBitMask=0x001f;<br />
ddsd.ddpfPixelFormat.dwRGBBitCount=16;<br />
ddsd.ddpfPixelFormat.dwFlags=DDPF_ALPHA|DDPF_RGB;<br />
ddsd.dwWidth = lpSize->cx;<br />
ddsd.dwHeight = lpSize->cy;<br />
<br />
<br />
res=lpDD4->CreateSurface(&ddsd,lplpDDS,NULL);<br />
if(res!=DD_OK) <br />
MessageBox(NULL,L"CreateSurface didn´t worked",NULL,NULL);<br />
<br />
switch(res){<br />
case DDERR_INVALIDPARAMS:<br />
MessageBox(NULL,L"CreateSurface INVALIDPARAMS",NULL,NULL);<br />
break;<br />
case DDERR_INVALIDOBJECT:<br />
MessageBox(NULL,L"CreateSurface INVALIDOBJECT",NULL,NULL);<br />
break;<br />
case DDERR_SURFACEBUSY:<br />
MessageBox(NULL,L"CreateSurface SURFACEBUSY",NULL,NULL);<br />
break;<br />
}<br />
}<br />
<br />
return 0;<br />
}
Please help anyone, I cannot understand what is wrong, it has to be something with the flags?
Thanks for your help!
|
|
|
|
|
Hello,
I'm wondering if anyone has experienced the
"Windows cannot find <path>\<filename>. Make sure you typed the name correctly, and then try again. To search for a file, click the Start button, and then click Search."
error when attempting to launch their MFC/C++ app. via double-clicking a file associated with the application. Oddly enough, the application will launch correctly when an associated file is dragged to the app's icon or to the app's document area (when it is open and active). This is a clue that DDE is working properly.
I have attempted to trap the error using a try/catch macro in InitInstance() and InitApplication() but to no avail. I don't think this error is being created from my application, but perhaps from Windows XP and/or Windows 2000, as the error occurs on both OS's.
Well, that's all I have for now. Thanks for your continued support.
-dotBomb
|
|
|
|
|
Is your app really located at <path>\<filename>? You can experience this behavior if you're incorrectly registering the application path. I've occasionally found this problem in my development environment, since the application working directory is just one level up the Debug or Release subdirectory.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
Want a Boost forum in Code Project? Vote here[^]!
|
|
|
|
|
Joaquín,
I understand your point, however the <path>\<filename> I wrote of is the path and filename of the associated file. This path and filename given in the error is actually the correct path and filename of the associated file I double-click. Think of this problem as double-clicking on a '.xls' file in order to launch excel with the '.xls' file loaded in the document area. Strange behavior from Windows, but not without explanation I'm sure.
Thank you,
-dotBomb
|
|
|
|
|
Umm... maybe the following will help you find the problem: Open the registry with regedit and look for HKEY_CLASSES_ROOT\.xxx (where xxx is the extension associated to your app). The value for this key should be something like "XXX.Document" , look for this and open the subkey shell/open/command : is what you see correct, or can you spot something ugly which might be explaining the problem? HTH.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
Want a Boost forum in Code Project? Vote here[^]!
|
|
|
|
|
Hey every one...
i got a question in c++
if i want to make a button and when I press it it will hold a key from my keybord.... let's say if i press the button then it will hold f1... so how to do it with c++ ?
|
|
|
|
|
can u explain your problem in detail
thanks
-----------------------------
"I Think It Will Help"
-----------------------------
Alok Gupta
visit me at http://www.thisisalok.tk
|
|
|
|
|
isn't it the opposite (when you press F1, it is like you had clicked on the button) ???
TOXCCT >>> GEII power
|
|
|
|
|
maybe you got me wrong... what i want is if i click a button then it will press key... i think it is something with the key event.....
|
|
|
|
|
I am using message reflection in myButton class so what i have in the message map is as below:
BEGIN_MESSAGE_MAP(myButton, CButton)
ON_CONTROL_REFLECT(BN_CLICKED, onButtonClick)
END_MESSAGE_MAP()
the prototype for onButtonClick() is afx_msg void onButtonClick()
and this works well. But i do want the parent as well to be notified so as mentioned in the MFC doc i modified the onButtonClick to return BOOL so it is then
afx_msg BOOL onButtonClick()
But this gives a compile time error :
error C2440: 'static_cast' : cannot convert from 'BOOL (__thiscall aegis::myButton::* )(void)' to 'AFX_PMSG'
None of the functions with this name in scope match the target type.
Any suggestions or is it a yet another bug in mfc.
thanks
|
|
|
|
|
got rid of the compilation error need to use ON_COMMAND_REFLECT_EX.
So now my code compiles and runs but the handler of the parent is not invoked why??
although i do have an onButtonClick in the parent.
|
|
|
|
|
Hello all. I'm having a terrible headache with a simple class... I have this class CTransfer, and I have two constructors:
<br />
class CTransferFileInfo;
class CTransferConfig;
<br />
CTransfer::CTransfer(CTransferFileInfo* pInfo, CTransferConfig* pConfig)<br />
{<br />
m_pFileInfo = pInfo;
m_pConfig = pConfig;
}<br />
<br />
CTransfer::CTransfer()<br />
{<br />
CTransfer::CTransfer(new CTransferFileInfo, NULL);<br />
}<br />
<br />
void CTransfer::SetFileInfo(CTransferFileInfo* pInfo)<br />
{<br />
if (m_pFileInfo) delete m_pInfo;<br />
m_pInfo = pInfo;<br />
}<br />
<br />
void CTransfer::SetConfig(CTransferConfig* pConfig)<br />
{<br />
if (m_pConfig) delete m_pConfig;<br />
m_pConfig = pConfig;<br />
}<br />
It does not seem to be rather difficult, is it? Well, the headache comes here. In another class, I create a CTransfer object with the default constructor, and call immediatly SetFileInfo, something like:
<br />
CTransfer* pTransfer = new CTransfer();<br />
pTransfer->SetFileInfo(pNewFileInfo);
So the problem goes in SetFileInfo. I debugged and realized that, when deleting m_pFileInfo... the member variable has random memory assigned! Worse, the variable m_pConfig, which is supposed to be NULL, has also a random memory address!
The thing goes worse. I debugged, and when entering CTransfer::CTransfer(CTransferFileInfo*, CTransferConfig*), it assigns the correct values to the variables. But after returning, the variables goes mad and change their value into a random memory address!
It's the first thing that this happens to me. Please, I'd appreciate any help. Thanks.
|
|
|
|
|
Kith Kahnan wrote:
CTransfer* pTransfer = new CTransfer();
What value do m_pFileInfo and m_pConfig have after this statement? I would guess they need to be set to NULL in CTransfer 's default constructor.
"Opinions are neither right nor wrong. I cannot change your opinion of me. I can, however, change what influences your opinion." - David Crow
|
|
|
|
|
This are the values:
m_pFileInfo = 0x008d3de0
m_pConfig = 0x008c7550
and pTransfer = 0x008d3d30
then, m_pFileInfo = m_pConfig = 0xcdcdcdcd
Thanks for your help.
|
|
|
|
|
I guess that the sentence CTransfer::CTransfer(new CTransferFileInfo(), NULL) is actually creating another instance of CTransfer... and of course, after leaving the method, the destructor is called... I guess I'd have to write much code anyway...
|
|
|
|
|
What happens when you just do this...
CTransfer::CTransfer()
{
m_pFileInfo = new CTransferFileInfo();
m_pConfig = NULL;
}
rather than this silliness...
CTransfer::CTransfer()
{
CTransfer::CTransfer(new CTransferFileInfo, NULL);
}
|
|
|
|
|