00001
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
00059
00060
00061
00062
00063 LRESULT OnInitDialog(UINT , WPARAM , LPARAM , BOOL& )
00064 {
00065
00066 CenterWindow();
00067
00068
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
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
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
00111 hr = ptr->Attach(SKYPE_PROTOCOL_VERSION, true);
00112 if (SUCCEEDED(hr)) {
00113 OutputDebugString("Connected\n");
00114 }
00115
00116
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 , WORD , HWND , BOOL& )
00132 {
00133 CAboutDlg dlg;
00134 dlg.DoModal();
00135 return 0;
00136 }
00137
00138 LRESULT OnOK(WORD , WORD wID, HWND , BOOL& )
00139 {
00140 CloseDialog(wID);
00141 return 0;
00142 }
00143
00144 LRESULT OnCancel(WORD , WORD wID, HWND , BOOL& )
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
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
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
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
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 };