// TODO: handle WM_WININICHANGE wxSize wxCalendarCtrl::DoGetBestSize() const { RECT rc; if ( !GetHwnd() || !MonthCal_GetMinReqRect(GetHwnd(), &rc) ) { return wxCalendarCtrlBase::DoGetBestSize(); } return wxRectFromRECT(rc).GetSize() + GetWindowBorderSize(); }
static void toggleCalendar(HWND hDlg) { if (monthcal == NULL) { INITCOMMONCONTROLSEX icex; icex.dwSize = sizeof(icex); icex.dwICC = ICC_DATE_CLASSES; InitCommonControlsEx(&icex); monthcal = CreateWindowEx(0, MONTHCAL_CLASS, _T(""), WS_BORDER | WS_POPUP, 0, 0, 0, 0, hDlg, NULL, NULL, NULL); /* subclass month calendar, so that it hides when looses focus */ monthcalOriginalWndProc = (WNDPROC) SetWindowLongPtr(monthcal, GWLP_WNDPROC, (LONG_PTR) MonthCalWndProc); } if (IsWindowVisible(monthcal)) ShowWindow(monthcal, SW_HIDE); else { RECT rc; int x; int y; SYSTEMTIME st; GetWindowRect(GetDlgItem(hDlg, IDC_PICKDATE), &rc); x = rc.left; y = rc.bottom; MonthCal_GetMinReqRect(monthcal, &rc); SetWindowPos(monthcal, NULL, x, y, rc.right, rc.bottom, SWP_SHOWWINDOW | SWP_NOZORDER); y = ASAPInfo_GetYear(edited_info); if (y > 0) { DWORD view; int month = ASAPInfo_GetMonth(edited_info); st.wYear = y; if (month > 0) { int day = ASAPInfo_GetDayOfMonth(edited_info); st.wMonth = month; if (day > 0) { st.wDay = day; view = MCMV_MONTH; } else { st.wDay = 1; view = MCMV_YEAR; } } else { st.wMonth = 1; st.wDay = 1; view = MCMV_DECADE; } (void) MonthCal_SetCurSel(monthcal, &st); (void) MonthCal_SetCurrentView(monthcal, view); } SetFocus(monthcal); } }
LRESULT CALLBACK Window_Calendar(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch(uMsg) { case WM_CREATE:{ int iMonths,iMonthsPast; DWORD dwCalStyle; RECT rc; HWND hCal; size_t idx; size_t dirty = 0; iMonths = api.GetIntEx(L"Calendar", L"ViewMonths", 3); iMonthsPast = api.GetIntEx(L"Calendar", L"ViewMonthsPast", 1); if(api.GetInt(L"Calendar", L"ShowDayOfYear", 1)) { wchar_t szTitle[32]; GetDayOfYearTitle(szTitle,iMonths); SetWindowText(hwnd,szTitle); } dwCalStyle = WS_CHILD|WS_VISIBLE; if(api.GetInt(L"Calendar",L"ShowWeekNums",0)) dwCalStyle|=MCS_WEEKNUMBERS; hCal = CreateWindowEx(0, MONTHCAL_CLASS, L"", dwCalStyle, 0,0,0,0, hwnd, NULL, NULL, NULL); if(!hCal) return -1; for(idx=0; idx<CALENDAR_COLOR_NUM; ++idx){ unsigned color = api.GetInt(L"Calendar", g_calendar_color[idx].reg, TCOLOR(TCOLOR_DEFAULT)); if(color != TCOLOR(TCOLOR_DEFAULT)){ dirty |= (1<<idx); MonthCal_SetColor(hCal, g_calendar_color[idx].mcsc, api.GetColor(color,0)); } } if(dirty&~1) SetXPWindowTheme(hCal, NULL, L""); MonthCal_GetMinReqRect(hCal,&rc);//size for a single month if(iMonths>1){ #define CALBORDER 4 #define CALTODAYTEXTHEIGHT 13 rc.right+=CALBORDER; rc.bottom-=CALTODAYTEXTHEIGHT; if(api.OS == TOS_2000){ rc.right+=2; rc.bottom+=2; } switch(iMonths){ /*case 1:*/ case 2: case 3: case 4: case 5: rc.right*=iMonths; break; case 6: rc.bottom*=3; /* fall through */ case 7: case 8: rc.right*=2; if(iMonths!=6) rc.bottom*=4; break; case 9: rc.bottom*=3; case 11: case 12: rc.right*=3; if(iMonths!=9) rc.bottom*=4; break; case 10: rc.right*=5; rc.bottom*=2; break; } rc.right-=CALBORDER; rc.bottom+=CALTODAYTEXTHEIGHT; if(api.OS >= TOS_VISTA) MonthCal_SizeRectToMin(hCal,&rc);//removes some empty space.. (eg at 4 months) }else{ if(rc.right<(LONG)MonthCal_GetMaxTodayWidth(hCal)) rc.right=MonthCal_GetMaxTodayWidth(hCal); } SetWindowPos(hCal,HWND_TOP,0,0,rc.right,rc.bottom,SWP_NOZORDER|SWP_NOACTIVATE); if(iMonthsPast){ SYSTEMTIME st,stnew; MonthCal_GetCurSel(hCal,&st); stnew=st; stnew.wDay=1; if(iMonthsPast>=stnew.wMonth){ --stnew.wYear; stnew.wMonth+=12; } stnew.wMonth-=(short)iMonthsPast; if(stnew.wMonth>12){ ++stnew.wYear; stnew.wMonth-=12; } // in case iMonthsPast is negative MonthCal_SetCurSel(hCal,&stnew); MonthCal_SetCurSel(hCal,&st); } SetFocus(hCal); AdjustWindowRectEx(&rc,WS_CAPTION|WS_POPUP|WS_SYSMENU|WS_VISIBLE,FALSE,0); SetWindowPos(hwnd,HWND_TOP,0,0, rc.right-rc.left,rc.bottom-rc.top, SWP_NOMOVE);//force to be on top if(m_bTopMost) SetWindowPos(hwnd,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE); api.PositionWindow(hwnd, (api.OS<TOS_WIN10 && api.OS>=TOS_WIN7 ? 11 : 0)); if(m_bAutoClose && GetForegroundWindow()!=hwnd) PostMessage(hwnd,WM_CLOSE,0,0); return 0;} case WM_ACTIVATE: if(!m_bTopMost){ if(LOWORD(wParam)==WA_ACTIVE || LOWORD(wParam)==WA_CLICKACTIVE){ SetWindowPos(hwnd,HWND_TOPMOST_nowarn,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE); }else{ SetWindowPos(hwnd,HWND_NOTOPMOST_nowarn,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE); // actually it should be lParam, but that's "always" NULL for other process' windows SetWindowPos(GetForegroundWindow(),HWND_TOP,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE); } } if(m_bAutoClose){ if(LOWORD(wParam)!=WA_ACTIVE && LOWORD(wParam)!=WA_CLICKACTIVE){ PostMessage(hwnd,WM_CLOSE,0,0);//adds a little more delay which is good } } break; case WM_DESTROY: Sleep(50);//we needed more delay... 50ms looks good (to allow T-Clock's FindWindow to work) 100ms is slower then Vista's native calendar PostQuitMessage(0); break; } return DefWindowProc(hwnd, uMsg, wParam, lParam); }
//Position the control void CalendarCtrl::PositionWindow(RECT* rect) { RECT temprect = {0}; RECT prect = {0} ; wyInt32 width, height, hmargin = 0, vmargin = 0; RECT calrect,timerect,okrect,cancelrect; GetClientRect(m_hwndparent, &prect); prect.right = prect.right - prect.left; prect.bottom = prect.bottom - prect.top; prect.left = 0; prect.top = 0; //Get all element handles GetClientRect(m_hwnd, &temprect); MonthCal_GetMinReqRect(GetDlgItem(m_hwnd,IDC_MONTHCALENDAR1),&calrect); GetWindowRect(GetDlgItem(m_hwnd,IDC_DATETIMEPICKER1),&timerect); GetWindowRect(GetDlgItem(m_hwnd,IDOK),&okrect); GetWindowRect(GetDlgItem(m_hwnd,IDCANCEL),&cancelrect); //calculate and modify the width and height based on the availabe space to best fit the window width = calrect.right - calrect.left; height = calrect.bottom - calrect.top + (okrect.bottom-okrect.top); hmargin = prect.right - rect->right; vmargin = prect.bottom - rect->top; if(height > vmargin) { if(rect->bottom - height > 0) { temprect.top = rect->bottom - height; } else { temprect.top = rect->top; } } else { temprect.top = rect->top; } if(width > hmargin) { if(rect->left - width > 0) { temprect.left = rect->left - width; } else { temprect.left = rect->left; if(temprect.top == rect->top) { temprect.top = rect->bottom; } else { if((rect->top - height)>0) { temprect.top = rect->top - height; } else { temprect.left = rect->left; if(temprect.top == rect->top) { temprect.top = rect->bottom; } } } } } else temprect.left = rect->right; //Postion all Controls MoveWindow(GetDlgItem(m_hwnd,IDC_MONTHCALENDAR1), -1, -1, width, calrect.bottom - calrect.top, TRUE); MoveWindow(GetDlgItem(m_hwnd,IDC_DATETIMEPICKER1), 0, (calrect.bottom - calrect.top)-1, width - (2*(okrect.right-okrect.left)), okrect.bottom-okrect.top+1, TRUE); MoveWindow(GetDlgItem(m_hwnd,IDOK), width - (2*(okrect.right-okrect.left)), (calrect.bottom - calrect.top)-2, (okrect.right-okrect.left), okrect.bottom-okrect.top+1, TRUE); MoveWindow(GetDlgItem(m_hwnd,IDCANCEL), width - (okrect.right-okrect.left)-1, (calrect.bottom - calrect.top)-2, (okrect.right-okrect.left), okrect.bottom-okrect.top+1, TRUE); //Position the window #ifndef COMMUNITY if(m_isForm) MoveWindow(m_hwnd, temprect.left+4, temprect.top, width, height, TRUE); else #endif MoveWindow(m_hwnd, temprect.left, temprect.top, width, height, TRUE); }
int APIENTRY _tWinMain(HINSTANCE hinst, HINSTANCE foo1, LPTSTR foo2, int foo3) { MSG msg; WNDCLASSEX wcex = {sizeof(wcex)}; HANDLE htray; HMENU hmenu; MENUITEMINFO mi = {sizeof(mi)}; INITCOMMONCONTROLSEX icex; RECT rect; int style; HWND hwnd; wcex.lpfnWndProc = WndProc; wcex.lpszClassName = WINDOW_CLASS; wcex.hCursor = LoadCursor(NULL, IDC_ARROW); RegisterClassEx(&wcex); icex.dwSize = sizeof(icex); icex.dwICC = ICC_DATE_CLASSES; InitCommonControlsEx(&icex); hwnd = CreateWindowEx(WS_EX_NOACTIVATE | WS_EX_TOPMOST, WINDOW_CLASS, WINDOW_TITLE, 0, 0, 0, 0, 0, NULL, NULL, hinst, NULL); if (!hwnd) return 1; style = GetWindowLong(hwnd, GWL_STYLE); if (style & WS_CAPTION) { style ^= WS_CAPTION; SetWindowLong(hwnd, GWL_STYLE, style); SetWindowPos(hwnd, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); } hcal = CreateWindowEx(0, MONTHCAL_CLASS, _T(""), WS_CHILD | WS_VISIBLE | MCS_NOTODAY | MCS_NOTRAILINGDATES | MCS_SHORTDAYSOFWEEK | MCS_NOSELCHANGEONNAV, 0, 0, 0, 0, hwnd, NULL, hinst, NULL); MonthCal_GetMinReqRect(hcal, &rect); SetWindowPos(hcal, NULL, 0, 0, rect.right, rect.bottom, SWP_NOZORDER | SWP_NOMOVE); SetWindowPos(hwnd, NULL, 0, 0, rect.right, rect.bottom, SWP_NOZORDER | SWP_NOMOVE); tti.hwnd = hwnd; tti.hcal = hcal; tti.hnotify = CreateEvent(NULL, TRUE, FALSE, NULL); tti.exit = FALSE; htray = CreateThread(NULL, 0, &TrayThreadProc, &tti, 0, NULL); if (!htray) return 1; hsubmenu = CreateMenu(); mi.fMask = MIIM_STRING | MIIM_ID; mi.wID = 1; mi.dwTypeData = EXIT_STRING; InsertMenuItem(hsubmenu, 0, TRUE, &mi); hmenu = CreateMenu(); mi.fMask = MIIM_SUBMENU; mi.hSubMenu = hsubmenu; InsertMenuItem(hmenu, 0, TRUE, &mi); WM_TASKBARCREATED = RegisterWindowMessageA(_T("TaskbarCreated")); while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } DestroyMenu(hmenu); DestroyMenu(hsubmenu); WaitForSingleObject(htray, 1000); CloseHandle(htray); return (int)msg.wParam; }