Guidance
指路人
g.yi.org
Guidance Forums / wxWidgets (wxWindows) in C++ / HICON,PROCESS_INFO, STARTUP_INFO !!!

Register 
新用户注册
Search 搜索
首页 
Home Home
Software
Upload

  
Forum List • Thread List • Reply • Refresh • New Topic • Search • Previous • Next First 1 Last
Message1. HICON,PROCESS_INFO, STARTUP_INFO !!!
#4704
Posted by: 2004-07-02 04:40:17
Hello,

I am trying to port an MFC existing code to a Linux system using the very helpful wxWidgets librairies but every thing is not that simple!!! I have an HICON defined which has to be initialized and will use the LoadIcon, ExtractIcon and DestroyIcon functions from MFC (the icon is found in the .exe file). I don't know what to use to do the same thing (I found wxIcon but it doesn't destroy the icon...)!!!

For PROCESS_INFORMATION and STARTUP_INFO, they are MFC defined in winbase.h which I will not be able to use on my Linux system and there are no informations about this anywhere in the site!! Please help!!!

Thank you,

Mona
Message2. Re: HICON,PROCESS_INFO, STARTUP_INFO !!!
#4706
Posted by: upCASE 2004-07-02 16:59:44
Hi!
HICON: Use wxIcon with an xpm embedded into the app. Have you tried deleting the wxIcon for "destroying" it?

PROCESS_INFORMATION: Check wxProcess, wxProcessEvent, wxGetProcessId and wxExecute. What do you want to do with the info?

STARTUPINFO: Try getting info with wxSystemSettings and wxSystemOptions. This will not lead to the same result, but better then nothing. Pass the needed values when creating a windows. Maybe ::wxGetDisplayName and ::wxSetDisplayName could be usefull for you.

Sorry that this is all I can offer. If you have more specific questions feel free to ask.
upCASE
-----------------------------------
If it was hard to write, it should be hard to read!- Do. Or do not. There is no try!
Message3. Re: HICON,PROCESS_INFO, STARTUP_INFO !!!
#4722
Posted by: 2004-07-05 22:19:21
Hello again,

This is what I have to change for the icon story:

MFC:
.h
HICON icon;
HICON error;

.cpp
(constructor)
icon = NULL;
error = wxGetApp()->LoadIcon(IDI_ERROR);
//IDI_ERROR is a .ico file

(destructor)
if((icon > (HICON) 1) && (icon != error))
  DestroyIcon(icon);

(functions)
CFileStatus status;

// Verify if the SW program exists, otherwise, set the icon to IDI_ERROR
if (!(CFile::GetStatus(pTemp ,status)))
 icon = error;

else         
// If the SW exist, get the icon from the .exe file
// (if no icon is associated to the SW, the default icon is preloaded in the dialog)
 icon = ::ExtractIcon(AfxGetInstanceHandle(),_T(pTemp),0);

The difference with HICON is that it is a handle to the icon and it can extract directly from the .exe file and then destroy it. I am still trying to see how I can change this, if you would have an idea please help!!! Thank you,

Mona
Message4. Re: HICON,PROCESS_INFO, STARTUP_INFO !!!
#4723
Posted by: upCASE 2004-07-05 22:48:53
Hi!
I'm just trying to understand what you want to do... Load an icon with wxWidgets, then check if an app exists using MFCs CFile and if it does extract it's icon, otherwise setting the HICON to a wxIcon ?? And all this should be running on Linux??

Do you want to:
1. Use MFC and wxWidgets together in one app (windows only)?
2. Use MFC and wxWidgets together in one app on both, windows & linux (not possible)?
3. Port your app to wxWidgets (thus asking how you do the same thing with wxWidgets)?

Sorry to be of no help right now, but I'm really confused. Please specify a little more and I'll see what I can do.
upCASE
-----------------------------------
If it was hard to write, it should be hard to read!- Do. Or do not. There is no try!
Message5. Re: HICON,PROCESS_INFO, STARTUP_INFO !!!
#4724
Posted by: 2004-07-05 23:30:13
Hello,


I am trying to port the MFC app (created to work on windows) to wxWidgets so I can use it on a Linux system (well it is not exactly Linux but it's supposed to have the same binaries). So it would be #3, I want every thing in the program to use wxWidgets in order to run on Linux. I am using the wxWindows-2.4.2 for now it's working pretty well except for the details I was talking about...

Sorry if I'm not clear..I'll try to clear things up:
So first I'm loading an icon from a file (in MFC it uses an icon from the resources) which is the "error". The real icon should be found from the .exe file and placed in "icon" and the path is located in pTemp.

This is what I have done for now, there are no sytax error but I don't know if it is going to work!!

.h
wxIcon    Icon;
wxIcon   Error;

.cpp
(constructor)
Icon.SetHICON(NULL);
BOOL err = Error.LoadFile( MM_ICON, wxBITMAP_TYPE_XBM);
//MM_ICON is the path to the .xpm file

(destructor)
// Destroy icon handle that has been created using ExtractIcon()
if((Icon.GetHICON() != NULL) && Icon != Error))
  Icon.~wxIcon();

(in function)
wxFileSystemHandler status;

// Verify if the SW program exists, otherwise, set the icon to IDI_ERROR
if(!(status.CanOpen(pTempSWProg)))
  Icon = Error;

else
  // If the SW exist, get the icon from the .exe file
  Icon.LoadFile(pTemp,wxBITMAP_TYPE_XBM);

It looks like it's working expect that it does not allow wxFileSystemHAndler because "cannot instantiate abstract class due to following members" (CanOpen, OpenFile...)

Thank you for your help!

Mona
     
Message6. Re: HICON,PROCESS_INFO, STARTUP_INFO !!!
#4726
Posted by: upCASE 2004-07-06 15:00:04
Hi!
The main problem is that on Linux/GTK/X apps don't have resources like icons, so you can't load the icon from the exe who's existance you tested. For that purpose you'll have to go with separate icon files you load and create when needed.
There's a way to embed images into the app on linux by using XPM files, but it's not like resources. See example...
It's  a very very bad idea to use something like "Icon.GetHICON()". While this may work on Windows it won't on any other platform. Use the methods mentioned in the reference. Try wxIcon::Ok();

Here's a small example. It's not very good and clean, but I just hacked it together in a few minutes. Maybe this helps a little. Note that the XPMs are included in the app.

Header

#ifndef __BASE_H
#define __BASE_H

#include <wx/wxprec.h>
#ifndef WX_PRECOMP
   #include <wx/wx.h>
#endif

class MainApp: public wxApp
{
  public:
      virtual bool OnInit();
};

class MainFrame: public wxFrame
{
    wxIcon*    Icon;
    wxIcon*    Error;
  public:
      MainFrame(const wxString &title, const wxPoint &pos, const wxSize &size);
      ~MainFrame();
      void OnQuit(wxCommandEvent &event);
      void OnIcon(wxCommandEvent &event);
  private:
      DECLARE_EVENT_TABLE()
};

enum
{
   ID_MAINWIN_QUIT = wxID_HIGHEST+1,
   ID_ICON
};
#endif

CPP


#include "base.h"
#include <wx/filename.h>
#include <wx/image.h>

#include "error.xpm"
#include "example.xpm"

IMPLEMENT_APP(MainApp)

bool MainApp::OnInit()
{
   MainFrame *win = new MainFrame("Frame", wxPoint (100, 100),
     wxSize(450, 340));
   win->Show(TRUE);
   SetTopWindow(win);

   return TRUE;
}


BEGIN_EVENT_TABLE(MainFrame, wxFrame)
   EVT_MENU(ID_MAINWIN_QUIT, MainFrame::OnQuit)
   EVT_MENU(ID_ICON, MainFrame::OnIcon)
END_EVENT_TABLE()

MainFrame::MainFrame(const wxString &title, const wxPoint &pos, const wxSize &size)
    : wxFrame((wxFrame *) NULL, -1, title, pos, size)
{
    wxInitAllImageHandlers();
    
    wxMenu *FileMenu = new wxMenu;
    wxMenuBar *MenuBar = new wxMenuBar;

    FileMenu->Append(ID_ICON, "&Get and set Icon");
    FileMenu->AppendSeparator();
    FileMenu->Append(ID_MAINWIN_QUIT, "&Quit");

    MenuBar->Append(FileMenu, "&File");
    SetMenuBar(MenuBar);
    
    Error = new wxIcon(error_xpm);
 }
MainFrame::~MainFrame()
{
    if(Icon->Ok() && Icon != Error)
        delete Icon;
}    
void MainFrame::OnIcon(wxCommandEvent & WXUNUSED(event))
{
    wxFileName fileName;
    if(!fileName.FileExists("Example.exe"))
    {   
        Icon = new wxIcon(*Error);
    }    
    else
    {
        Icon = new wxIcon(example_xpm);
    }    
        
    SetIcon(*Icon);
}
void MainFrame::OnQuit(wxCommandEvent & WXUNUSED(event))
{
    Close(TRUE);
}

upCASE
-----------------------------------
If it was hard to write, it should be hard to read!- Do. Or do not. There is no try!
Message7. Re: HICON,PROCESS_INFO, STARTUP_INFO !!!
#4732
Posted by: 2004-07-07 02:43:49
Hello,

Thank you very much for your help, I think it is going to work...I cannot check it at this moment because I'm still working on a Windows computer but I'll keep you posted.
------------------------------------------
Now, for the PROCESS_INFO, it is more complicated because the structure uses:
typedef struct _PROCESS_INFORMATION {
    HANDLE hProcess;
    HANDLE hThread;
    DWORD dwProcessId;
    DWORD dwThreadId;
} PROCESS_INFORMATION, *PPROCESS_INFORMATION, *LPPROCESS_INFORMATION;

and I am supposed to use it as follows:
.h
PROCESS_INFORMATION ProcessInfo;

.cpp
(cons)
ProcessInfo.dwProcessId = 0;

Then I use it to start an application and thus to createprocess,  check if the application is in process and I also have to use the dwProcessId
fct(...,PROCESS_INFORMATION *pAppsProcessInfo){
(pAppsProcessInfo->dwProcessId > 0) ...
(dwCurrentProcessID==pAppsProcessInfo->dwProcessId)...
}

fct()
if(ProcessInfo.dwProcessId != 0)
  CloseApplication(ProcessInfo.dwProcessId);


wxProcess can see if the process exists but does not check if it is currently in process and does not give the ID information...Please help!!!

----------------------------------------------

For STARTUP_INFO,

.h
STARTUPINFO        StartupInfo;

.cpp
(cons)
// Initialise the startup struct used when starting the application
memset(&StartupInfo,0,sizeof(StartupInfo));   
StartupInfo.cb = sizeof(StartupInfo);
  
// Set flag so the application allways start maximized
StartupInfo.dwFlags = STARTF_USESHOWWINDOW;
StartupInfo.wShowWindow = SW_MAXIMIZE;

It is then used in CreatProcess which has the parameters:
BOOL CreateProcess(
  LPCTSTR lpApplicationName,
                         // pointer to name of executable module
  LPTSTR lpCommandLine,  // pointer to command line string
  LPSECURITY_ATTRIBUTES lpProcessAttributes,  // process security attributes
  LPSECURITY_ATTRIBUTES lpThreadAttributes,   // thread security attributes
  BOOL bInheritHandles,  // handle inheritance flag
  DWORD dwCreationFlags, // creation flags
  LPVOID lpEnvironment,  // pointer to new environment block
  LPCTSTR lpCurrentDirectory,   // pointer to current directory name
=>  LPSTARTUPINFO lpStartupInfo,  // pointer to STARTUPINFO
=>  LPPROCESS_INFORMATION lpProcessInformation  // pointer to PROCESS_INFORMATION
);

I have never worked with processes and startup_info so I am an amateur in this!!! :(

Thank you sooo much,

Mona
Message8. Re: HICON,PROCESS_INFO, STARTUP_INFO !!!
#4741
Posted by: upCASE 2004-07-07 15:24:49
Hi!
"I have never worked with processes and startup_info so I am an amateur in this!!!"
No prob :)
As I allready said: Try wxExecute(). I'm still not sure what your app is actually doing, but from what I can see you only need the PID of the process to create and nothing else. If the parent process doesn't need control over the child process you won't need wxProcess at all. Maybe think of wxProcess as the process info and an event handler or callback of some sort.
If you don't need to catch termination events of the child process, use wxExecute and execute the child process ASYNC.
upCASE
-----------------------------------
If it was hard to write, it should be hard to read!- Do. Or do not. There is no try!
Message9. Re: HICON,PROCESS_INFO, STARTUP_INFO !!!
#4827
Posted by: upCASE 2004-07-15 14:56:32
Hi!
Allthough I allready had a conversation with Mona via email, I thought it would be a good idea to close this thread here by posting a solution.
#ifndef __BASE_H
#define __BASE_H

#include <wx/wxprec.h>
#ifndef WX_PRECOMP
   #include <wx/wx.h>
#endif

#include <wx/utils.h> //for wxExecute
#include <wx/process.h> //for wxProcess

class MainApp: public wxApp
{
  public:
      virtual bool OnInit();
};

class MainFrame: public wxFrame
{
    wxProcess* process; //Process callback
    long pid; //the PID of the new process
	
    wxTextCtrl* text;
    wxLogTextCtrl* log;
  public:
      MainFrame(const wxString &title, const wxPoint &pos, const wxSize &size);
      void OnQuit(wxCommandEvent &event);
      //Starts a new Process
      void OnStartProcess(wxCommandEvent &event);
      // Kills an existing Process
      void OnKillProcess(wxCommandEvent &event);
      //Checks if the Process with PID is running
      void OnCheckProcess(wxCommandEvent & WXUNUSED(event));
      //Called when the process terminates
      void OnProcessTerminate(wxProcessEvent & event);
  private:
      DECLARE_EVENT_TABLE()
};

enum
{
   ID_MAINWIN_QUIT = wxID_HIGHEST+1,
   ID_STARTPROCESS,
   ID_KILLPROCESS,
   ID_CHECKPROCESS
};
#endif

#include "base.h"
#include <wx/textdlg.h>

IMPLEMENT_APP(MainApp)
//Start the app
bool MainApp::OnInit()
{
   MainFrame *win = new MainFrame("Process Test", wxPoint (100, 100),
     wxSize(350, 150));
   win->Show(TRUE);
   SetTopWindow(win);

   return TRUE;
}

BEGIN_EVENT_TABLE(MainFrame, wxFrame)
   EVT_MENU(ID_MAINWIN_QUIT, MainFrame::OnQuit)
   EVT_MENU(ID_STARTPROCESS, MainFrame::OnStartProcess)
   EVT_MENU(ID_KILLPROCESS, MainFrame::OnKillProcess)
   EVT_MENU(ID_CHECKPROCESS, MainFrame::OnCheckProcess)
   EVT_END_PROCESS(123, MainFrame::OnProcessTerminate)
END_EVENT_TABLE()

MainFrame::MainFrame(const wxString &title, const wxPoint &pos, const wxSize &size)
    : wxFrame((wxFrame *) NULL, -1, title, pos, size)
{
    wxMenu *FileMenu = new wxMenu;
    wxMenuBar *MenuBar = new wxMenuBar;

    FileMenu->Append(ID_STARTPROCESS, "&Start Process");
    FileMenu->Append(ID_CHECKPROCESS, "&Check if Process is running");
    FileMenu->Append(ID_KILLPROCESS, "&Kill Process");
    FileMenu->AppendSeparator();
    FileMenu->Append(ID_MAINWIN_QUIT, "&Quit");

    MenuBar->Append(FileMenu, "&File");
    SetMenuBar(MenuBar);

    CreateStatusBar(2);
    SetStatusText("The wonderfull Process example!");
    
    process = NULL;
    pid = 0;
    
    text = new wxTextCtrl(this, -1, "",
                        wxDefaultPosition,wxDefaultSize,wxTE_READONLY | wxTE_MULTILINE  );
    log = new wxLogTextCtrl(text);
    wxLog::SetActiveTarget(log);
}

void MainFrame::OnStartProcess(wxCommandEvent & WXUNUSED(event))
{
    process = new wxProcess(this,123); //this (Mainframe) should handle the EVT_END_PROCESS with id 123
    
    wxString app = ::wxGetTextFromUser("Please enter the name of the process to start (e.g. calc)");
    
    //Start a new Process (app) that runs asynchronously. Process is used as an event handle callback.
    pid = wxExecute(app,wxEXEC_ASYNC | wxEXEC_NOHIDE, process);
    if( pid == 0 )
        wxLogMessage("Process could not be started...");
    else if( pid == -1 )
        wxLogMessage("Process was connected to a running one...");
    else
       wxLogMessage( wxString::Format("Process started with PID %ld", pid) );
}

void MainFrame::OnKillProcess(wxCommandEvent & WXUNUSED(event))
{
   //Send a signal to process with PID. SIGTERM means "end" or "close". It's not like TerminateProcess().
   int err = wxProcess::Kill( pid, wxSIGTERM );
   wxString str;
   switch(err)
   {
       case wxKILL_OK:
           str = "Ok, Process terminated";
       break;
       case wxKILL_BAD_SIGNAL:
           str = "Bad Signal";
       break;
       case wxKILL_ACCESS_DENIED:
           str = "Acces to Process denied";
       break;
       case wxKILL_NO_PROCESS:
           str = "There's no such Process...";
       break;              
       case wxKILL_ERROR:
           str = "Error using wxProcess::Kill()";
       break; 
   }
  wxLogMessage(str);
}    

void MainFrame::OnCheckProcess(wxCommandEvent & WXUNUSED(event))
{
   //SIGNONE sends a signal that isn't handled in a special way by the process.
   //This results in checking wether the process exists or not.
   int err = wxProcess::Kill( pid, wxSIGNONE );
   
   if(err != wxKILL_OK)
      wxLogMessage("There is no such Process...");
   else
      wxLogMessage("Process found!"); 
}   

//This is called once the process terminates.
//This happens either when the user closes the process, or we send a SIGTERM.
//In both cases when recieve this event and get the PID and exitcode from it.
void MainFrame::OnProcessTerminate(wxProcessEvent & event)
{
  wxLogMessage( wxString::Format("Process -> PID: %d exited with code %d",
                                    event.GetPid(), event.GetExitCode()));
}

void MainFrame::OnQuit(wxCommandEvent & WXUNUSED(event))
{
    Close(TRUE);
}[/code
upCASE
-----------------------------------
If it was hard to write, it should be hard to read!- Do. Or do not. There is no try!
Forum List • Thread List • Reply • Refresh • New Topic • Search • Previous • Next First 1 Last
掌柜推荐
 
 
 
 
 
 
 
 
 
 
 
 
© Wed 2021-7-28  Guidance Laboratory Inc.
Email:webmaster1g.yi.org Hits:0