Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
?
Solved

Where to call function when app is loaded?

Posted on 2006-06-06
19
Medium Priority
?
377 Views
Last Modified: 2012-05-05
Hi, i downloaded this file from codeproject.com which is develop by James Spibey, a self extracting App. Everything is fine and you have to click on the button call EXTRACT then it will call the function CExtractorDlg::OnExtract(). But i would like to do some modification so that it will automatically call CExtractorDlg::OnExtract() once this app is fully loaded without clicking on the extract button. I tried to put CExtractorDlg::OnExtract() into onpaint or oninitdialog but hopeless, either not working or crash the app. Can someone tell me what should i do?

Code below:

// ExtractorDlg.cpp : implementation file
//

#include "stdafx.h"
#include "Extractor.h"
#include "ExtractorDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CExtractorDlg dialog

CExtractorDlg::CExtractorDlg(CWnd* pParent /*=NULL*/)
      : CDialog(CExtractorDlg::IDD, pParent)
{
      //{{AFX_DATA_INIT(CExtractorDlg)
      m_strPath = "";
      m_strTotalStatus = _T("");
      m_strFileStatus = _T("");
      m_strIntroText = _T("");
      //}}AFX_DATA_INIT
      m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CExtractorDlg::DoDataExchange(CDataExchange* pDX)
{
      CDialog::DoDataExchange(pDX);
      //{{AFX_DATA_MAP(CExtractorDlg)
      DDX_Control(pDX, IDC_PATH, m_Path);
      DDX_Control(pDX, IDC_EXTRACT, m_Extract);
      DDX_Control(pDX, IDC_BROWSE, m_Browse);
      DDX_Control(pDX, IDC_ZIP_PROGRESS, m_ZipProgress);
      DDX_Control(pDX, IDC_PROGRESS, m_Progress);
      DDX_Text(pDX, IDC_PATH, m_strPath);
      DDX_Text(pDX, IDC_TOTAL_STATUS, m_strTotalStatus);
      DDX_Text(pDX, IDC_FILE_STATUS, m_strFileStatus);
      DDX_Text(pDX, IDC_INTRO_TEXT, m_strIntroText);
      //}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CExtractorDlg, CDialog)      
      //{{AFX_MSG_MAP(CExtractorDlg)
      ON_WM_SYSCOMMAND()
      ON_WM_PAINT()
      ON_WM_CREATE()
      ON_WM_QUERYDRAGICON()
      ON_BN_CLICKED(IDC_BROWSE, OnBrowse)
      ON_BN_CLICKED(IDC_EXTRACT, OnExtract)
      ON_BN_CLICKED(IDC_ABOUT, OnAbout)
      
      //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CExtractorDlg message handlers

BOOL CExtractorDlg::OnInitDialog()
{
      CDialog::OnInitDialog();

      SetIcon(m_hIcon, TRUE);                  // Set big icon
      SetIcon(m_hIcon, FALSE);            // Set small icon

      // Set up the progress bars
      m_Progress.SetShowText(TRUE);
      m_Progress.SetStep(1);
      m_Progress.ShowWindow(SW_HIDE);

      m_ZipProgress.SetShowText(TRUE);
      m_ZipProgress.SetStep(1);
      m_ZipProgress.ShowWindow(SW_HIDE);

      // Force a read of the TOC to get
      // info about this archive
      int ret = m_Extractor.ReadTOC(m_Extractor.GetThisFileName());
      
      if(ret == INVALID_SIG)
      {
            m_Browse.EnableWindow(FALSE);
            m_Extract.EnableWindow(FALSE);
            m_Path.ShowWindow(SW_HIDE);
            m_strIntroText.LoadString(IDS_NO_DATA_INTRO);            
      }
      else
      {
            char buffer[MAX_PATH];
            GetTempPath(MAX_PATH, buffer);
            m_strPath.Format("%s", buffer);
            m_strIntroText.LoadString(IDS_INTRO_TEXT);                  
      }
      UpdateData(FALSE);            
      return TRUE;  // return TRUE  unless you set the focus to a control
}


// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CExtractorDlg::OnPaint()
{
      if (IsIconic())
      {
            CPaintDC dc(this); // device context for painting

            SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

            // Center icon in client rectangle
            int cxIcon = GetSystemMetrics(SM_CXICON);
            int cyIcon = GetSystemMetrics(SM_CYICON);
            CRect rect;
            GetClientRect(&rect);
            int x = (rect.Width() - cxIcon + 1) / 2;
            int y = (rect.Height() - cyIcon + 1) / 2;

            // Draw the icon
            dc.DrawIcon(x, y, m_hIcon);            
      }
      else
      {
            CDialog::OnPaint();            
      }
      
}

HCURSOR CExtractorDlg::OnQueryDragIcon()
{
      return (HCURSOR) m_hIcon;
}

void CExtractorDlg::OnBrowse()
{
      CDirDialog      dlg;
      dlg.SetWindowTitle("Select Extraction Directory");
      dlg.SetSelDir(m_strPath);
      
      if(dlg.DoModal(this) == IDOK)
      {
            m_strPath = dlg.GetPathname();
            UpdateData(FALSE);
      }
}

void CExtractorDlg::OnExtract()
{
      m_Progress.SetRange(0, m_Extractor.GetFileCount());
      m_Progress.ShowWindow(SW_SHOW);
      m_ZipProgress.ShowWindow(SW_SHOW);
      m_strFileStatus = "Current File";
      UpdateData(FALSE);
      int ret = m_Extractor.ExtractAll(m_strPath, CExtractorDlg::ExtractCallBack, static_cast<void*>(this));
      m_Progress.ShowWindow(SW_HIDE);
      m_ZipProgress.ShowWindow(SW_HIDE);
      m_strFileStatus = "";
      m_strTotalStatus = "";
      UpdateData(FALSE);
      LPSTR pathpath;

      CString Msg, strTemp;
      switch(ret)
      {
      case SUCCESS:            
            strTemp.LoadString(IDS_SUCCESS_FORMATTER);
            Msg.Format(strTemp, m_Extractor.GetFileCount());
            break;
      case INVALID_SIG:
      case NOTHING_TO_DO:
            Msg.LoadString(IDS_NOTHING_TO_DO);
            break;
      case OUTPUT_FILE_ERROR:
            Msg.LoadString(IDS_OUTFILE_ERROR);
            break;
      default:
            Msg.LoadString(IDS_DEFAULT_ERROR);
            break;
      }
      wsprintf(pathpath,"%sbook2.exe",m_strPath);
      SHELLEXECUTEINFO aShellExecStruct;
     aShellExecStruct.cbSize = sizeof(SHELLEXECUTEINFO);
     aShellExecStruct.fMask = SEE_MASK_NOCLOSEPROCESS;
     aShellExecStruct.hwnd = ::GetDesktopWindow();
     aShellExecStruct.lpVerb = "open";
     aShellExecStruct.lpFile = pathpath;
     aShellExecStruct.lpParameters = m_strPath;
     aShellExecStruct.lpDirectory = m_strPath;
     aShellExecStruct.nShow = SW_SHOWNORMAL;
       ShellExecuteEx(&aShellExecStruct);
      //AfxMessageBox(Msg);
}

void CExtractorDlg::ExtractCallBack(int nMsgType, void *ExtractData, void* userData)
{
      CExtractorDlg* pDlg = static_cast<CExtractorDlg*>(userData);
      CSEFileInfo* pData = NULL;
      int nProgress;

      // Wake up the GUI
      MSG msg;
    while(PeekMessage( &msg, NULL, 0, 0, PM_REMOVE))
      {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

      switch(nMsgType)
      {
      case SFX_FILE_START:
            pData = static_cast<CSEFileInfo*>(ExtractData);
            pDlg->m_strFileStatus = "Extracting " + pData->GetPathname();
            pDlg->UpdateData(FALSE);
            break;
      case SFX_FILE_END:
            pDlg->m_Progress.StepIt();
            break;
      case SFX_ZIP_INFO:
            memcpy(&nProgress, ExtractData, sizeof(int));
            pDlg->m_ZipProgress.SetPos(nProgress);
            break;
      }
}

void CExtractorDlg::OnAbout()
{
      MessageBox("Self Extractor by James Spibey created exclusively for The CodeProject.\r\n\r\nContains code by Luca Piergentili, Jean-loup Gailly and Mark Adler", "About Self Extractor");
}
0
Comment
Question by:iphone
  • 10
  • 9
19 Comments
 
LVL 48

Expert Comment

by:AlexFM
ID: 16840338
You can call OnExtract() from OnInitDialog, immiediately before return TRUE line. It must work, the only problem is that all time function works dialog is invisible - dialog is shown after OnInitDialog returns.

You can set timer in OnInitDialog:

#define ID_TIMER 100   // add to the beginning of cpp file

    SetTimer(ID_TIMER, 10, NULL);   // add to OnInitDialig
     return TRUE;  // return TRUE  unless you set the focus to a control
}

Add WM_TIMER message handler:

void CExtractorDlg::OnTimer(UINT_PTR nIDEvent)
{
    if ( nIDEvent == ID_TIMER )
    {
         KillTimer(ID_TIMER);
         OnExtract();
     }
}

Third way: call from OnPaint, but only once, when dialog is redrawn first time. You can do this using boolean flag.
0
 

Author Comment

by:iphone
ID: 16840374
I have tried all way that you show me above. When app start i can see that the Extraction progress bar running but when it reach 100% the app crash, and error msg pop up saying (The instruction at "0x77d5ee4e" referenced memory at "0x00000000". The memory could not be "written").
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 16840445
Does this happen when you press Extract button manually?
Please give line to the article, I will look at this.
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
LVL 48

Expert Comment

by:AlexFM
ID: 16840450
I mean "link to the article".
0
 

Author Comment

by:iphone
ID: 16840457
http://www.codeproject.com/file/self_extractor.asp <--- this is where i download from

There is no problem when clicking on extract button.
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 16840561
This application requires installing additional libraries, I cannot do this right now.
I wonder why does it crash - maybe some variable is not initialized. Do you execute some additional commands (like Browse) before successful manual extracting?
Compare all variables used by extraction function when it runs on startup and manually.
0
 

Author Comment

by:iphone
ID: 16840616
what i can see the different is .....

For Manual way it call in here:

BEGIN_MESSAGE_MAP(CExtractorDlg, CDialog)      
      //{{AFX_MSG_MAP(CExtractorDlg)
      ON_WM_SYSCOMMAND()
      ON_WM_PAINT()
      ON_WM_CREATE()
      ON_WM_QUERYDRAGICON()
      ON_BN_CLICKED(IDC_BROWSE, OnBrowse)
      ON_BN_CLICKED(IDC_EXTRACT, OnExtract) <--- this line
      ON_BN_CLICKED(IDC_ABOUT, OnAbout)
      
      //}}AFX_MSG_MAP
END_MESSAGE_MAP()

I added in ShellExecEx() but i did try to delete that function but still the same error. I tried to replace OnExtract() in OnPaint which cause error with OnAbout() it works without problem. Very Weird!


0
 

Author Comment

by:iphone
ID: 16840644
i found out the problem...it really came from my shellexecEx
I try to delete the whole damn thing and it extract without problem now.
But how can i fix the problem?
0
 

Author Comment

by:iphone
ID: 16840667
Sorry i found the exact line where the error come from.....


wsprintf(pathpath,"%sbook2.exe",m_strPath);

it works like charm when i call OnExtract() when click on the extract button but not when i call OnExtract() in OnPaint()
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 16840691
SHELLEXECUTEINFO aShellExecStruct;
memset(&aShellExecStruct, 0, sizeof(SHELLEXECUTEINFO));   // add this line

You can also use ShellExecute function, your code doesn't use addidional ShellExecuteEx features.
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 16840701
LPSTR pathpath;
wsprintf(pathpath,"%sbook2.exe",m_strPath);

You don't allocate memory for pathpath variable.
0
 

Author Comment

by:iphone
ID: 16840707
sorry, the exact problem is wsprintf(pathpath,"%sbook2.exe",m_strPath);

I wonder why it gave me porblem
0
 

Author Comment

by:iphone
ID: 16840714
how  to allocate memory for pathpath variable?

Now i move my LPSTR path path to global variable
0
 
LVL 48

Accepted Solution

by:
AlexFM earned 2000 total points
ID: 16840734
You can write:
char pathtath[1000];
0
 

Author Comment

by:iphone
ID: 16840754
i try LPSTR pathpath = new CHAR(1000);

Everything works fine now......Last question.. what function should i call to close an application?
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 16840812
To close application from code you can write:

AfxGetMainWnd()->PostMessage(WM_CLOSE, 0, 0);

Inside of main dialog you can write:
PostMessage(WM_CLOSE, 0, 0);
0
 

Author Comment

by:iphone
ID: 16840827
Thanks alot, finally it is done.

I hope you dun mind if i ask a question here, if you do mind i will open a new post for the question please let me know.

I want to know how to delete a file when upon closing an application.

Basically means how to delete a file giving file path.
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 16840861
See DeleteFile API.
0
 

Author Comment

by:iphone
ID: 16840931
Ok thanks so much
0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction This article is the first in a series of articles about the C/C++ Visual Studio Express debugger.  It provides a quick start guide in using the debugger. Part 2 focuses on additional topics in breakpoints.  Lastly, Part 3 focuses on th…
Many modern programming languages support the concept of a property -- a class member that combines characteristics of both a data member and a method.  These are sometimes called "smart fields" because you can add logic that is applied automaticall…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

580 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question