static char sccsid[] = "@(#) $Id: //bas/710_REL/src/krn/rfc/rfcpumpd.cpp#1 $ SAP"; /*src----------------------------------------------------------------* * rfcpumpd.cpp -- SAP RFC: Sample Windows Pump With Progress Dialog * *-------------------------------------------------------------------* * SAP AG Walldorf * Systeme, Anwendungen und Produkte in der Datenverarbeitung * * (C) Copyright SAP AG 1998 *-------------------------------------------------------------------* * * A simple Windows pump for use in RFC programs. * The code is provided as is. * Modify this code to suite your requirements. * *end-----------------------------------------------------------------*/ #ifndef DONT_USE_STRICT # define STRICT 1 //needed with MFC projects #endif #define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers #include #ifndef _INC_COMMCTRL # include #endif #include #include "saprfc.h" #include "rfcpump.h" ///////////////////////////////////////////////////////////////////////////// // cancel dialog window proc BOOL CALLBACK RfcPumpDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM /*lParam*/) { HWND hwnd; switch(message) { case WM_INITDIALOG: //SetWindowText(hDlg,...); ::EnableMenuItem(GetSystemMenu(hDlg, FALSE), SC_CLOSE, MF_GRAYED); hwnd = GetDlgItem(hDlg, IDCANCEL); if (NULL != hwnd) { ::ShowWindow(hwnd, SW_HIDE); ::EnableWindow(hwnd, FALSE); } return TRUE; case WM_COMMAND: if (IDCANCEL == wParam) { CRfcPump* p = (CRfcPump*)GetWindowLong(hDlg, DWL_USER); if (NULL != p) p->SetAbort(TRUE); ::EnableWindow(::GetParent(hDlg), TRUE); ::DestroyWindow(hDlg); p->SetClosed(); //close pump } return TRUE; } return FALSE; } //@doc----------------------------------------------------------------- /*--------------------------------------------------------------------- * @mfunc | CRfcPump | CRfcPump | Construct with progress/cancel dialog * * This construct a instance. * * If

has the value * the dialog is created immediately. * If it has the value * the dialog is created only if needed. * *

should be the instance from the module from * which the dialog template should be loaded. *

is the Id of the dialog template. * the CANCEL button (if any should have the ID IDCANCEL. * *

should be the handle from the parent Windows. * It is generaly the main Windows from the application. * * If

is NULL, no progress indicator message * are sent. Changing the values of

and

* change the speed at which the progress indicator is updated * * @xref */ CRfcPump::CRfcPump(RFCP_DIALOG_MODE dm, //@parm immediate/differed // dialog creation HINSTANCE hInst, //@parm module instance UINT DlgID, //@parm dialog template id HWND hWndParent, //@parm parent Windows UINT idProgress, //@parm progress indicator ID UINT uiRange, //@parm progress indicator range UINT uiStep //@parm progress indicator step ) : m_bUserAbort(FALSE), m_hWndParent(hWndParent), m_hWndDlg(0), m_hWndDlgG(0), m_hWndProgress(0), m_State(RFCP_INIT), m_hInst(hInst), m_DlgID(DlgID), m_idProgress(idProgress), m_uiRange(uiRange), m_uiStep(uiStep) { if (RFCPDM_IMEDIATE == dm) CreateCancelDialog(hInst, DlgID, hWndParent, idProgress, uiRange, uiStep) ; else { if (0 == hWndParent) hWndParent = ::GetActiveWindow(); m_hWndParent = hWndParent; if (0 != m_hWndParent && ::GetDesktopWindow() != m_hWndParent) EnableWindow(m_hWndParent, FALSE); } } /*--------------------------------------------------------------------- * @mfunc HWND | CRfcPump | CreateCancelDialog | Delayed dialog creation. * * This method is called internally, and may be called * externally if the instance has been * created with the default constructor. * *

should be the instance from the module from * which the dialog template should be loaded. *

is the Id of the dialog template. * the CANCEL button (if any should have the ID IDCANCEL. * *

should be the handle from the parent Windows. * It is generaly the main Windows from the application. * * If

is NULL, no progress indicator message * are sent. Changing the values of

and

* change the speed at which the progress indicator is updated * * @xref */ HWND CRfcPump::CreateCancelDialog(HINSTANCE hInst, //@parm module instance UINT DlgID, //@parm dialog template ID HWND hWndParent, //@parm parent Windows UINT idProgress, //@parm progress indicator ID UINT uiRange, //@parm progress indicator range UINT uiStep //@parm progress indicator step ) { if (0 == hWndParent) hWndParent = ::GetActiveWindow(); m_hWndParent = hWndParent; if (0 != m_hWndParent && ::GetDesktopWindow() != m_hWndParent) EnableWindow(m_hWndParent, FALSE); m_hWndDlgG = m_hWndDlg = ::CreateDialog(hInst, MAKEINTRESOURCE(DlgID), m_hWndParent, RfcPumpDlgProc); if (0 != m_hWndDlg) { SetWindowLong(m_hWndDlg, DWL_USER, (LONG)this); m_State = RFCP_CREATED; if (NULL != idProgress) { m_hWndProgress = GetDlgItem(m_hWndDlg, idProgress) ; if (NULL != m_hWndProgress) { ::SetFocus(m_hWndProgress); ::SendMessage(m_hWndProgress, PBM_SETRANGE, 0, MAKELPARAM(0, uiRange)); ::SendMessage(m_hWndProgress, PBM_SETSTEP, uiStep, 0L); } } } else m_State = RFCP_ERROR; return m_hWndDlg; }//CRfcPump::CreateCancelDialog /*--------------------------------------------------------------------- * @mfunc HWND | CRfcPump | Pump | The inner Windows message pump * * This method is called internally by * and can be called externally by users which want to control * exactly when the Windows message pump is wound. * * On each call, the progress bar is step steps * if a progress indicator exist on the dialog. * * Change this method if you want to change the progress * indicator handling * * @xref * * @rdesc Continue * @flag TRUE | abort not requested * @flag FALSE| abort requested */ BOOL CRfcPump::Pump() { if ( (RFCP_VISIBLE == m_State || RFCP_CANCEL == m_State) && m_hWndDlgG && m_hWndProgress && !m_bUserAbort) ::SendMessage(m_hWndProgress, PBM_STEPIT, 0, 0L); MSG msg; while (!m_bUserAbort && ::PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE)) { if (!m_hWndDlgG || !IsDialogMessage(m_hWndDlgG, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } return !m_bUserAbort; }//CRfcPump::Pump() /*--------------------------------------------------------------------- * Show the dialog which is initialy hidden */ void CRfcPump::Show(BOOL b) { if (!m_bUserAbort && m_hWndDlgG) { ::ShowWindow(m_hWndDlgG, (b ? SW_SHOW: SW_HIDE)); if (TRUE == b) { m_State = RFCP_VISIBLE; } else { m_State = RFCP_CREATED; ::ShowWindow(GetDlgItem(m_hWndDlgG, IDCANCEL), SW_HIDE); ::EnableWindow(GetDlgItem(m_hWndDlgG, IDCANCEL), FALSE); } } }//CRfcPump::Show /*--------------------------------------------------------------------- * Enable the cancel button which is initialy hidden */ void CRfcPump::EnableCancel(void) { if (!m_bUserAbort && m_hWndDlgG) { if (RFCP_VISIBLE != m_State) Show(TRUE); if (m_hWndProgress) ::SendMessage(m_hWndProgress, PBM_SETPOS, 0, 0L); ::ShowWindow(GetDlgItem(m_hWndDlgG, IDCANCEL), SW_SHOW); ::EnableWindow(GetDlgItem(m_hWndDlgG, IDCANCEL), TRUE); m_State = RFCP_CANCEL; } }//CRfcPump::EnableCancel /*--------------------------------------------------------------------- * mfunc HWND | CRfcPump | RfcPump | The RFC Windows message pump * * Call between and * or before or . * * rdesc Continue or abort * flag if = 0 | RFC_RC as returned from * flag if 0 | Abort has been requested */ int CRfcPump::RfcPump(RFC_HANDLE hRfc) { RFC_RC rfc_rc; BOOL bContinue = TRUE; for ( ; RFC_RETRY == (rfc_rc = RfcListen(hRfc)) && TRUE == (bContinue = Pump()) ; ) {;}//NOP if (0 == bContinue) return -1; return rfc_rc; } #define TICK_SPAN( dwS, dwE) \ ((dwE >= dwS) ? (dwE - dwS) : ((ULONG_MAX - dwS) + dwE)) /*--------------------------------------------------------------------- * @mfunc HWND | CRfcPump | RfcPump | The RFC Windows message pump * * Call between and * or before or . * * - Calls internally * - Shows the dialog after

milliseconds, * - Enable the cancel button after

milliseconds * - Returns users'cancel request or RFC state. * * Assume that the dialog has been created or cached! * (by constructor or by ) * * Exist also as an overloaded member without dialog. * I.e. AbortProc only. * * @xref * * @rdesc Continue or abort * @flag if = 0 | RFC_RC as returned from * @flag if 0 | Abort has been requested */ int CRfcPump::RfcPump(RFC_HANDLE hRfc, //@parm module instance DWORD dwHidden, //@parm msTime before Progress // Dialog is shown DWORD dwCancel) //@parm ms, Time before Cancel // Button is enabled { RFC_RC rfc_rc; BOOL bContinue = TRUE; DWORD dwStart = GetTickCount(); while ( RFC_RETRY == (rfc_rc = RfcListen(hRfc)) && TRUE == (bContinue = Pump()) ) { RFCP_PUMPSTATE s = GetState(); if (RFCP_CANCEL != s) { DWORD dwEnd = GetTickCount(); DWORD dwSpan = TICK_SPAN(dwStart, dwEnd); if (dwSpan > dwHidden) { if (RFCP_INIT == s) { CreateCancelDialog(m_hInst, m_DlgID, m_hWndParent, m_idProgress, m_uiRange, m_uiStep) ; Show(TRUE); } else if (RFCP_CREATED == s) Show(TRUE); } if (RFCP_VISIBLE == GetState() && dwSpan > dwCancel) EnableCancel(); } } if (0 == bContinue) return -1; return rfc_rc; }