MainDlg.h

Go to the documentation of this file.
00001 // MainDlg.h : interface of the CMainDlg class
00002 //
00004 
00005 #pragma once
00006 
00007 typedef std::map<long, CallInfo*> CallList;
00008 typedef std::map<std::string, Tariff*> TariffMap;
00009 typedef enum TariffType TariffType;
00010 
00016 class CMainDlg : public CDialogImpl<CMainDlg>, public CUpdateUI<CMainDlg>,
00017         public CMessageFilter, public CIdleHandler,
00018         public IDispEventImpl<IDD_MAINDLG,CMainDlg,&DIID__ISkypeEvents,&LIBID_SKYPE4COMLib,1,0>
00019 {
00020 private:
00021         TariffCalculator* calculator;
00022         CallList calls;
00023         CStatic costLabel;
00024         float totalCost;
00025         IConversionPtr converter;
00026         static const int SKYPE_PROTOCOL_VERSION = 5;
00027 
00028 public:
00029         enum { IDD = IDD_MAINDLG };
00030         ISkypePtr ptr;
00031 
00032 
00033         virtual BOOL PreTranslateMessage(MSG* pMsg)
00034         {
00035                 return CWindow::IsDialogMessage(pMsg);
00036         }
00037 
00038         virtual BOOL OnIdle()
00039         {
00040                 return FALSE;
00041         }
00042 
00043         BEGIN_SINK_MAP(CMainDlg)
00044                 SINK_ENTRY_EX(IDD_MAINDLG, DIID__ISkypeEvents, 0x8, &OnCallStatusChange)
00045         END_SINK_MAP()
00046 
00047         BEGIN_UPDATE_UI_MAP(CMainDlg)
00048         END_UPDATE_UI_MAP()
00049 
00050         BEGIN_MSG_MAP(CMainDlg)
00051                 MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
00052                 COMMAND_ID_HANDLER(ID_APP_ABOUT, OnAppAbout)
00053                 COMMAND_ID_HANDLER(IDOK, OnOK)
00054                 COMMAND_ID_HANDLER(IDCANCEL, OnCancel)
00055         END_MSG_MAP()
00056 
00057 
00058         // Handler prototypes (uncomment arguments if needed):
00059         //      LRESULT MessageHandler(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
00060         //      LRESULT CommandHandler(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
00061         //      LRESULT NotifyHandler(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/)
00062 
00063         LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
00064         {
00065                 // center the dialog on the screen
00066                 CenterWindow();
00067 
00068                 // set icons
00069                 HICON hIcon = (HICON)::LoadImage(_Module.GetResourceInstance(), MAKEINTRESOURCE(IDR_MAINFRAME), 
00070                         IMAGE_ICON, ::GetSystemMetrics(SM_CXICON), ::GetSystemMetrics(SM_CYICON), LR_DEFAULTCOLOR);
00071                 
00072                 SetIcon(hIcon, TRUE);
00073                 
00074                 HICON hIconSmall = (HICON)::LoadImage(_Module.GetResourceInstance(), MAKEINTRESOURCE(IDR_MAINFRAME), 
00075                         IMAGE_ICON, ::GetSystemMetrics(SM_CXSMICON), ::GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR);
00076                 SetIcon(hIconSmall, FALSE);
00077 
00078                 costLabel = GetDlgItem(IDC_STC3);
00079                 totalCost = 0.0f;
00080 
00081                 // register object for message filtering and idle updates
00082                 CMessageLoop* pLoop = _Module.GetMessageLoop();
00083                 ATLASSERT(pLoop != NULL);
00084                 pLoop->AddMessageFilter(this);
00085                 pLoop->AddIdleHandler(this);
00086 
00087                 UIAddChildWindowContainer(m_hWnd);
00088 
00092                 calculator = new TariffCalculator();
00093                 std::string tariffsFile("tariffs.dat");
00094                 calculator->parse(tariffsFile);
00095 
00096                 // Initialize an instance of ythe
00097                 HRESULT hr;
00098                 hr = ptr.CreateInstance(__uuidof(Skype));
00099                 if (FAILED(hr)) {
00100                         MessageBox("Failed to create Skype instance!\n", "Error");
00101                         exit(-1);
00102                 }
00103                 
00106                 converter.CreateInstance(__uuidof(Conversion));
00107                 
00108                 try {
00109                         OutputDebugString("Connecting...\n");
00110                         //hr = ptr->Client->Start(false, false);
00111                         hr = ptr->Attach(SKYPE_PROTOCOL_VERSION, true);
00112                         if (SUCCEEDED(hr)) {
00113                                 OutputDebugString("Connected\n");
00114                         }
00115 
00116                         // Hook up for event notifications
00117                         hr = DispEventAdvise(ptr);
00118                         if (FAILED(hr)) {
00119                                 MessageBox("Failed to connect event handlers!\n", "Error");
00120                                 exit(-1);
00121                         }
00122                 }
00123                 catch (_com_error e) {
00124                         _tprintf(_T("There was an error: %s %s %s\n"),
00125                                 e.Error(), e.ErrorMessage(), e.Description());
00126                 }
00127 
00128                 return TRUE;
00129         }
00130 
00131         LRESULT OnAppAbout(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
00132         {
00133                 CAboutDlg dlg;
00134                 dlg.DoModal();
00135                 return 0;
00136         }
00137 
00138         LRESULT OnOK(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
00139         {
00140                 CloseDialog(wID);
00141                 return 0;
00142         }
00143 
00144         LRESULT OnCancel(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
00145         {
00146                 CloseDialog(wID);
00147                 return 0;
00148         }
00149 
00150         void CloseDialog(int nVal)
00151         {
00153                 DispEventUnadvise(ptr);
00154 
00156                 TariffMap tariffs = calculator->getTariffs();
00157                 for (TariffMap::iterator it = tariffs.begin();
00158                         it != tariffs.end(); it++) {
00159                                 Tariff* tariff = it->second;
00160                                 delete tariff;
00161                 }
00162 
00163                 delete calculator;
00164 
00166                 for (CallList::iterator it = calls.begin();
00167                         it != calls.end(); it++) {
00168                                 CallInfo* callInfo = it->second;
00169                                 delete callInfo->callerCountry;
00170                                 delete callInfo;
00171                 }
00172 
00173 
00174                 DestroyWindow();
00175                 ::PostQuitMessage(nVal);
00176         }
00177 
00178         // Event handlers
00179         void __stdcall OnCallStatusChange(ICall* pCall, enum TCallStatus status) {
00180                 std::ostringstream str;
00181 
00182                 USES_CONVERSION;
00183                 
00185                 if (status == clsInProgress) {
00186                         str << "Call in progress with " << (LPCTSTR)OLE2T(pCall->PartnerHandle.GetBSTR());
00187                         IUserPtr user = ptr->GetUser(pCall->PartnerHandle);
00188 
00189                         CallInfo* callInfo = new CallInfo();
00190                         callInfo->callId = pCall->Id;
00191                         callInfo->duration = 0L;
00192 
00193                         std::string* country = new std::string(OLE2T(user->Country.GetBSTR()));
00194                         callInfo->callerCountry = country;
00195 
00196                         TariffType tariffType = getTariffType();
00197                         callInfo->tariffType = tariffType;
00198 
00199                         calls[pCall->Id] = callInfo;
00200                 }
00201                 else if (status == clsRouting) {
00202                         str << "Routing ...";
00203                 }
00204                 else if (status == clsRinging) {
00205                         str << "Ringing ...";
00206                 }
00207                 else if (status == clsFailed) {
00208                         str << "Call failed, reason code = " << pCall->FailureReason;
00209                 }
00210                 else if (status == clsFinished) {
00211                         str << "Call # " << pCall->Id << " finished, duration: " << pCall->Duration << " seconds.";
00212                         
00213                         // Retrieve the call from the active calls list
00214                         CallList::const_iterator it = calls.find(pCall->Id);
00215                         if (it == calls.end()) {
00216                                 OutputDebugString("Call Id not found!");
00217                                 return;
00218                         }
00219 
00220                         CallInfo* callInfo = it->second;
00221                         callInfo->duration = pCall->Duration;
00222                         float cost = calculator->getCost(callInfo);
00223                         totalCost += cost;
00224                         std::ostringstream ostr;
00225                         ostr << totalCost;
00226         
00227                         costLabel.SetWindowText(ostr.str().c_str());
00228                         
00229                         // Remove the call from the active calls map
00230                         calls.erase(pCall->Id);
00231                 }
00232 
00233                 CListBox listbox = GetDlgItem(IDC_LST1);
00234                 listbox.AddString(str.str().c_str());
00235                 OutputDebugString(str.str().c_str());
00236         }
00237 
00241         TariffType getTariffType(void) {
00242                 using namespace boost::posix_time;
00243                 using namespace boost::gregorian;
00244                 ptime now = second_clock::local_time();
00245 
00246                 date d = now.date();
00247                 greg_weekday day = d.day_of_week();
00248                 
00249                 unsigned short weekday = day.as_number();
00250                 if (weekday == 0 || weekday == 6) {
00251                         return TariffType::WEEKEND;
00252                 }
00253 
00254                 time_duration t = now.time_of_day();
00255                 long hours = t.hours();
00256                 if (hours >= 6 && hours <= 18) {
00257                         return TariffType::DAY;
00258                 }
00259                 else {
00260                         return TariffType::EVENING;
00261                 }
00262         }
00263 
00264         virtual HRESULT GetFuncInfoFromId(const IID& iid, DISPID dispidMember, LCID lcid, _ATL_FUNC_INFO& info) {
00265                 // class base class implementation
00266                 HRESULT hr = IDispEventImpl<IDD_MAINDLG, CMainDlg,
00267                         &DIID__ISkypeEvents, &LIBID_SKYPE4COMLib, 1, 0>::
00268                         GetFuncInfoFromId(iid, dispidMember,lcid, info);
00269                 if (SUCCEEDED(hr)) {
00270                         if (::InlineIsEqualGUID(iid, DIID__ISkypeEvents)) {
00271                                 for(long l = 0; l < info.nParams; l++) {
00272                                         if(info.pVarTypes[l] == VT_USERDEFINED) {
00273                                                 info.pVarTypes[l] = VT_I4;
00274                                         }
00275                                 }
00276                         }
00277                 }
00278                 return hr;
00279         }
00280 };

Generated on Wed Sep 20 09:36:02 2006 for Skype Call Cost Estimator by  doxygen 1.4.6