Changeset 772 in dev for trunk/ab5.0/abdev/abdev/src/MainFrame.cpp
- Timestamp:
- Aug 29, 2009, 7:55:19 AM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/ab5.0/abdev/abdev/src/MainFrame.cpp
r749 r772 10 10 void CreateProcessWithStdHandle( const std::string &appPath, const std::string &cmdLine, bool isShowWindow = true ) 11 11 { 12 std::string argsStr = "\""+ appPath + "\" " + cmdLine;12 std::string argsStr = '\"' + appPath + "\" " + cmdLine; 13 13 STARTUPINFO si; 14 14 PROCESS_INFORMATION pi; … … 21 21 si.hStdError = GetStdHandle(STD_ERROR_HANDLE); 22 22 23 char args[8192]; 24 lstrcpy( args, argsStr.c_str() ); 25 26 CreateProcess( NULL, args, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi ); 23 std::vector<char> args( argsStr.c_str(), argsStr.c_str() + argsStr.size() + 1 ); 24 25 CreateProcess( NULL, &args[0], NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi ); 27 26 CloseHandle( pi.hProcess ); 28 27 CloseHandle( pi.hThread ); 29 28 } 29 30 #ifdef HAVE_WINDOWS_7_SDK 31 32 #define MSGFLT_ADD 1 33 34 #pragma push_macro("_WIN32_WINNT") 35 #undef _WIN32_WINNT 36 #define _WIN32_WINNT 0x0601 37 #include <dwmapi.h> 38 #pragma pop_macro("_WIN32_WINNT") 39 40 #define WM_DWMSENDICONICTHUMBNAIL 0x0323 41 #define WM_DWMSENDICONICLIVEPREVIEWBITMAP 0x0326 42 43 // Windows 7タスクバーにボタンとして表示させるためのウィンドウ。 44 // 各MDI子ウィンドウ (wndTarget) と1対1に対応する。 45 class DummyWindowForTaskbarButton : public ATL::CWindowImpl<DummyWindowForTaskbarButton>, boost::noncopyable 46 { 47 public: 48 DECLARE_WND_CLASS(TEXT("DummyWindow For Taskbar Button")); 49 50 BEGIN_MSG_MAP(DummyWindowForTaskbarButton) 51 MESSAGE_HANDLER_EX(WM_DWMSENDICONICTHUMBNAIL, OnDwmSendIconicThumnail) 52 MESSAGE_HANDLER_EX(WM_DWMSENDICONICLIVEPREVIEWBITMAP, OnDwmSendIconicLivePreviewBitmap) 53 MSG_WM_ACTIVATE(OnActivate) 54 END_MSG_MAP() 55 56 explicit DummyWindowForTaskbarButton(HWND hwndTarget, const char* title) : 57 wndTarget(hwndTarget) 58 { 59 HWND hwndDummy = Create( hOwner, CRect( -32000, -32000, 1, 1 ), title, 60 WS_BORDER | WS_SYSMENU | WS_CAPTION, WS_EX_NOACTIVATE); 61 SetIcon( wndTarget.GetIcon( FALSE ), FALSE ); 62 SetIcon( wndTarget.GetIcon( TRUE ), TRUE ); 63 64 BOOL iconicRepresentation = TRUE; 65 HRESULT hr; 66 hr = DwmSetWindowAttribute( 67 *this, 68 DWMWA_FORCE_ICONIC_REPRESENTATION, 69 &iconicRepresentation, 70 sizeof iconicRepresentation); 71 BOOL iconicBitmap = TRUE; 72 hr = DwmSetWindowAttribute( 73 *this, 74 DWMWA_HAS_ICONIC_BITMAP, 75 &iconicBitmap, 76 sizeof iconicBitmap); 77 } 78 79 ~DummyWindowForTaskbarButton() 80 { 81 } 82 private: 83 void OnActivate(UINT state, BOOL /*minimized*/, HWND /*hwndOther*/) 84 { 85 if (state == WA_ACTIVE) 86 { 87 if (ActiveBasic::IDE::Program::mainFrame.IsIconic()) 88 { 89 ActiveBasic::IDE::Program::mainFrame.ShowWindow(SW_RESTORE); 90 } 91 SetForegroundWindow(ActiveBasic::IDE::Program::mainFrame); 92 ActiveBasic::IDE::Program::mainFrame.MDIActivate(wndTarget); 93 wndTarget.Invalidate(FALSE); 94 } 95 } 96 97 class BitmapMemoryDC : public WTL::CDC, boost::noncopyable 98 { 99 public: 100 explicit BitmapMemoryDC(HBITMAP hbmp) : 101 WTL::CDC(::CreateCompatibleDC(0)), 102 bmp(hbmp), 103 hbmpOld(SelectBitmap(bmp)) 104 { 105 } 106 BitmapMemoryDC(int width, int height, void*& bits) : 107 WTL::CDC(::CreateCompatibleDC(0)), 108 bmp(CreateDIBSection32(m_hDC, width, height, bits)), 109 hbmpOld(SelectBitmap(bmp)) 110 { 111 } 112 ~BitmapMemoryDC() 113 { 114 SelectBitmap(hbmpOld); // この後、CDCとbmpのデストラクタでそれぞれDeleteDCとDeleteObjectがなされる。 115 } 116 WTL::CBitmap& GetBitmap() 117 { 118 return bmp; 119 } 120 private: 121 WTL::CBitmap bmp; 122 HBITMAP hbmpOld; 123 }; 124 125 LRESULT OnDwmSendIconicThumnail(UINT, WPARAM, LPARAM lp) 126 { 127 HRESULT hr = SetIconicThumbnail(HIWORD(lp), LOWORD(lp)); 128 return 0; 129 } 130 131 LRESULT OnDwmSendIconicLivePreviewBitmap(UINT, WPARAM, LPARAM) 132 { 133 HRESULT hr = SetIconicLivePreviewBitmap(); 134 return 0; 135 } 136 137 HRESULT SetIconicThumbnail(int maximumWidth, int maximumHeight) 138 { 139 int widthBmp, heightBmp; 140 BitmapMemoryDC dcSrc(CreateBitmap(widthBmp, heightBmp)); 141 if (dcSrc) 142 { 143 int width, height; // dcSrcの縦横比に合わせて縮小する 144 if (widthBmp * maximumHeight > maximumWidth * heightBmp) // (widthBmp / heightBmp > maximumWidth / maximumHeight) 145 { 146 width = maximumWidth; 147 height = heightBmp * maximumWidth / widthBmp; 148 } 149 else 150 { 151 height = maximumHeight; 152 width = widthBmp * maximumHeight / heightBmp; 153 } 154 void* pvBits; 155 BitmapMemoryDC dc(width, height, pvBits); 156 if (dc) 157 { 158 StretchBlt(dc, 0, 0, width, height, dcSrc, 0, 0, widthBmp, heightBmp, SRCCOPY); 159 return DwmSetIconicThumbnail(*this, dc.GetBitmap(), DWM_SIT_DISPLAYFRAME); 160 } 161 } 162 return HRESULT_FROM_WIN32(GetLastError()); 163 } 164 165 HRESULT SetIconicLivePreviewBitmap() 166 { 167 int w, h; 168 WTL::CBitmap bmp(CreateBitmap(w, h)); 169 if (bmp) 170 { 171 POINT pt = {}; 172 wndTarget.MapWindowPoints(hOwner, &pt, 1); 173 pt.y += GetSystemMetrics(SM_CYMENU); 174 return DwmSetIconicLivePreviewBitmap(*this, bmp, &pt, wndTarget.IsZoomed() ? 0 : DWM_SIT_DISPLAYFRAME); 175 } 176 return HRESULT_FROM_WIN32(GetLastError()); 177 } 178 179 static void SetAlpha(DWORD& pixel) 180 { 181 pixel |= 0xff000000; 182 } 183 184 HBITMAP CreateBitmap(int& width, int& height) 185 { 186 RECT rcClient; 187 wndTarget.GetClientRect(&rcClient); 188 void* pvBits; 189 BitmapMemoryDC dc(rcClient.right, rcClient.bottom, pvBits); 190 if (dc) 191 { 192 int wndNum = GetWndNum(wndTarget); 193 if (wndNum != -1) 194 { 195 CPoint origin(0, 0); 196 wndTarget.ClientToScreen( &origin ); 197 CRect rcWindow; 198 wndTarget.GetWindowRect( rcWindow ); 199 origin -= rcWindow.TopLeft(); 200 dc.SetWindowOrg( origin ); // クライアント領域の(0, 0)がビットマップの(0, 0)になるよう合わせる 201 wndTarget.Print( dc, PRF_CHECKVISIBLE | PRF_ERASEBKGND | PRF_CHILDREN | PRF_CLIENT ); 202 width = rcClient.right; 203 height = rcClient.bottom; 204 DWORD* pdwBits = static_cast<DWORD*>(pvBits); 205 std::for_each(pdwBits, pdwBits + width * height, SetAlpha); 206 return dc.GetBitmap().Detach(); 207 } 208 } 209 return 0; 210 } 211 // 32ビットトップダウンのDIBセクションを作る補助 212 static HBITMAP CreateDIBSection32(HDC hdc, int width, int height, void*& pb) 213 { 214 BITMAPINFO bi; 215 ZeroMemory(&bi.bmiHeader, sizeof bi.bmiHeader); 216 bi.bmiHeader.biSize = sizeof bi.bmiHeader; 217 bi.bmiHeader.biWidth = width; 218 bi.bmiHeader.biHeight = -height; // トップダウンDIBにする必要があるらしい 219 bi.bmiHeader.biPlanes = 1; 220 bi.bmiHeader.biBitCount = 32; 221 return CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, &pb, 0, 0); 222 } 223 224 CWindow wndTarget; 225 }; 226 227 class TaskbarList 228 { 229 typedef boost::shared_ptr<DummyWindowForTaskbarButton> DummyWindowForTaskbarButtonPtr; 230 typedef std::map<HWND, DummyWindowForTaskbarButtonPtr> WindowMap; 231 public: 232 TaskbarList(HWND hwndFrame) : 233 wndFrame(hwndFrame) 234 { 235 HRESULT hr = taskbarList.CoCreateInstance( CLSID_TaskbarList ); 236 if ( FAILED( hr ) ) { 237 return; 238 } 239 HRESULT hr2 = taskbarList->HrInit(); 240 if ( FAILED( hr2 ) ) { 241 taskbarList.Release(); 242 return; 243 } 244 } 245 246 void RegisterTab(HWND hwndChild, const char* title) 247 { 248 assert( hwndChild ); 249 if (taskbarList) 250 { 251 assert( windowMap.find(hwndChild) == windowMap.end() ); 252 DummyWindowForTaskbarButtonPtr p(new DummyWindowForTaskbarButton(hwndChild, title)); 253 windowMap.insert(std::make_pair(hwndChild, p)); 254 //タスクバーボタンに追加 255 HRESULT hr = taskbarList->RegisterTab(*p, wndFrame); 256 } 257 } 258 259 void RegisterTab(HWND hwndChild) 260 { 261 ATL::CWindow wnd = hwndChild; 262 ATL::CString title; 263 wnd.GetWindowText(title); 264 RegisterTab(hwndChild, title); 265 } 266 267 void UnregisterTab(HWND hwndChild) 268 { 269 if (taskbarList) 270 { 271 WindowMap::iterator it = windowMap.find(hwndChild); 272 assert( it != windowMap.end() ); 273 HRESULT hr = taskbarList->UnregisterTab(*it->second); 274 it->second->DestroyWindow(); 275 windowMap.erase( it ); 276 } 277 } 278 279 void InvalidateIconicBitmaps(HWND hwndChild) 280 { 281 DwmInvalidateIconicBitmaps(*mapAt(hwndChild)); 282 } 283 284 void SetTabActivate(HWND hwndChild) 285 { 286 if (taskbarList) 287 { 288 taskbarList->SetTabActive(*mapAt(hwndChild), wndFrame, 0); 289 } 290 } 291 292 void SetTabOrder( HWND hwndChild, HWND hwndInsertBefore ) 293 { 294 if (taskbarList) 295 { 296 taskbarList->SetTabOrder(*mapAt(hwndChild), 297 hwndInsertBefore 298 ? static_cast<HWND>(*mapAt(hwndInsertBefore)) 299 : 0); 300 } 301 } 302 private: 303 DummyWindowForTaskbarButtonPtr mapAt(HWND hwndChild) 304 { 305 DummyWindowForTaskbarButtonPtr p = windowMap[hwndChild]; 306 assert(p); 307 return p; 308 } 309 CWindow wndFrame; 310 ATL::CComPtr<ITaskbarList3> taskbarList; 311 WindowMap windowMap; 312 }; 313 #endif HAVE_WINDOWS_7_SDK 314 315 #ifdef HAVE_WINDOWS_7_SDK 316 MainFrame::MainFrame() : 317 TaskbarButtonCreated( RegisterWindowMessage( TEXT("TaskbarButtonCreated") ) ) 318 { 319 if ( TaskbarButtonCreated != 0 ) 320 { 321 typedef BOOL WINAPI CWMF(UINT, DWORD); 322 HMODULE hmodUser = GetModuleHandle( TEXT("user32.dll") ); 323 assert( hmodUser != 0 ); 324 if ( CWMF* pcwmf = reinterpret_cast<CWMF*>( GetProcAddress( hmodUser, "ChangeWindowMessageFilter" ) ) ) 325 { 326 pcwmf(TaskbarButtonCreated, MSGFLT_ADD); 327 pcwmf(WM_DWMSENDICONICTHUMBNAIL, MSGFLT_ADD); 328 pcwmf(WM_DWMSENDICONICLIVEPREVIEWBITMAP, MSGFLT_ADD); 329 } 330 } 331 } 332 #else 333 MainFrame::MainFrame() {} 334 #endif 30 335 31 336 void MainFrame::Resized() … … 59 364 //Status bar 60 365 int height_Statusbar; 61 SendMessage(hStatusBar,SB_GETRECT,0,( long)&StatusRect);366 SendMessage(hStatusBar,SB_GETRECT,0,(LPARAM)&StatusRect); 62 367 height_Statusbar=StatusRect.bottom; 63 368 … … 227 532 hOwner = m_hWnd; 228 533 extern WNDPROC oldMainFrameWndProc; 229 oldMainFrameWndProc = (WNDPROC)::GetWindowLong( hOwner, GWL_WNDPROC ); 230 ::SetWindowLongPtr( hOwner, GWL_WNDPROC, reinterpret_cast<LONG_PTR>(WindowFunc) ); 534 oldMainFrameWndProc = (WNDPROC)::SetWindowLongPtr( hOwner, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(WindowFunc) ); 231 535 232 536 SetupWindow(hOwner); … … 234 538 //テキストエディタフォント設定 235 539 ResetTextEditFont(hOwner); 236 237 238 540 239 541 return 0; … … 549 851 void MainFrame::OnPaint( HDC ) 550 852 { 551 PAINTSTRUCT ps; 552 HDC hdc = this->BeginPaint( &ps ); 553 554 HBRUSH hBrush = CreateSolidBrush( GetSysColor( COLOR_3DFACE ) ); 853 WTL::CPaintDC dc( m_hWnd ); 555 854 556 855 RECT rect; 557 856 this->GetClientRect( &rect ); 558 857 559 FillRect( hdc, &rect, hBrush ); 560 561 DeleteObject( hBrush ); 562 563 this->EndPaint( &ps ); 858 dc.FillRect( &rect, GetSysColorBrush( COLOR_3DFACE ) ); 564 859 } 565 860 … … 600 895 ::UpdateWindow(hChild); 601 896 602 c har *pTemp=MdiInfo[WndNum]->pMdiTextEdit->buffer;897 const char *pTemp=MdiInfo[WndNum]->pMdiTextEdit->buffer; 603 898 604 899 //行の先頭インデックスを取得(取得する行の番号はwParamで渡される) … … 628 923 } 629 924 925 ::LRESULT MainFrame::OnTaskbarButtonCreated( ::UINT msg, ::WPARAM, ::LPARAM ) 926 { 927 #ifdef HAVE_WINDOWS_7_SDK 928 if ( msg == 0 ) { // 念のため確認 929 return 0; 930 } 931 taskbarList.reset(new TaskbarList(*this)); 932 #endif 933 return 0; 934 } 935 936 void MainFrame::AddChildWindow( HWND hwndChild ) 937 { 938 #ifdef HAVE_WINDOWS_7_SDK 939 taskbarList->RegisterTab( hwndChild ); 940 #endif 941 } 942 943 void MainFrame::DeleteChildWindow( HWND hwndChild ) 944 { 945 #ifdef HAVE_WINDOWS_7_SDK 946 taskbarList->UnregisterTab( hwndChild ); 947 #endif 948 } 949 950 void MainFrame::ActivateChildWindow( HWND hwndChild ) 951 { 952 #ifdef HAVE_WINDOWS_7_SDK 953 taskbarList->SetTabActivate( hwndChild ); 954 #endif 955 } 956 957 void MainFrame::SetTabOrder( HWND hwndChild, HWND hwndInsertBefore ) 958 { 959 #ifdef HAVE_WINDOWS_7_SDK 960 taskbarList->SetTabOrder( hwndChild, hwndInsertBefore ); 961 #endif 962 } 963 964 void MainFrame::InvalidateBitmap( HWND hwndChild ) 965 { 966 #ifdef HAVE_WINDOWS_7_SDK 967 taskbarList->InvalidateIconicBitmaps( hwndChild ); 968 #endif 969 } 970 630 971 void MainFrame::OnCmdNew( UINT uNotifyCode, int nID, CWindow wndCtl ) 631 972 { … … 639 980 char temporary[MAX_PATH]; 640 981 641 FileType=DialogBox(hResInst,MAKEINTRESOURCE(IDD_NEWFILE),hOwner, (DLGPROC)DlgNewFile);982 FileType=DialogBox(hResInst,MAKEINTRESOURCE(IDD_NEWFILE),hOwner,DlgNewFile); 642 983 if(FileType==-1) return; 643 984 … … 745 1086 { 746 1087 //文字コードを指定して保存 747 DialogBox(hResInst,MAKEINTRESOURCE(IDD_CODE_SAVE),m_hWnd, (DLGPROC)nkfDlgCodeSave);1088 DialogBox(hResInst,MAKEINTRESOURCE(IDD_CODE_SAVE),m_hWnd,nkfDlgCodeSave); 748 1089 } 749 1090 750 1091 void MainFrame::OnCmdAllSave( UINT uNotifyCode, int nID, CWindow wndCtl ) 751 1092 { 752 for ( int i=0;i<MdiInfo.size();i++){753 if( MdiInfo[i]->hwnd) SaveDocument(MdiInfo[i]->hwnd,NULL);1093 foreach( MDIINFO *mi, MdiInfo ){ 1094 if(mi->hwnd) SaveDocument(mi->hwnd,NULL); 754 1095 } 755 1096 if( projectInfo.IsOpened() ) … … 824 1165 TextEdit_GetSel(WndNum,&CharRange); 825 1166 826 HGLOBAL hGlobal= (char *)GlobalAlloc(GMEM_MOVEABLE,CharRange.cpMax-CharRange.cpMin+1);1167 HGLOBAL hGlobal=GlobalAlloc(GMEM_MOVEABLE,CharRange.cpMax-CharRange.cpMin+1); 827 1168 char *pTemp=(char *)GlobalLock(hGlobal); 828 1169 memcpy(pTemp,MdiInfo[WndNum]->pMdiTextEdit->buffer+CharRange.cpMin,CharRange.cpMax-CharRange.cpMin); … … 885 1226 TextEdit_GetSel(WndNum,&CharRange); 886 1227 887 HGLOBAL hGlobal= (char *)GlobalAlloc(GMEM_MOVEABLE,CharRange.cpMax-CharRange.cpMin+1);1228 HGLOBAL hGlobal=GlobalAlloc(GMEM_MOVEABLE,CharRange.cpMax-CharRange.cpMin+1); 888 1229 char *pTemp=(char *)GlobalLock(hGlobal); 889 1230 memcpy(pTemp,MdiInfo[WndNum]->pMdiTextEdit->buffer+CharRange.cpMin,CharRange.cpMax-CharRange.cpMin); … … 1030 1371 void MainFrame::OnCmdFind( UINT uNotifyCode, int nID, CWindow wndCtl ) 1031 1372 { 1032 DialogBox(hResInst,MAKEINTRESOURCE(IDD_FIND),m_hWnd, (DLGPROC)DlgFind);1373 DialogBox(hResInst,MAKEINTRESOURCE(IDD_FIND),m_hWnd,DlgFind); 1033 1374 } 1034 1375 1035 1376 void MainFrame::OnCmdPermutation( UINT uNotifyCode, int nID, CWindow wndCtl ) 1036 1377 { 1037 DialogBox(hResInst,MAKEINTRESOURCE(IDD_PERMUTATION),m_hWnd, (DLGPROC)DlgPermutation);1378 DialogBox(hResInst,MAKEINTRESOURCE(IDD_PERMUTATION),m_hWnd,DlgPermutation); 1038 1379 } 1039 1380 … … 1046 1387 void MainFrame::OnCmdStringCount( UINT uNotifyCode, int nID, CWindow wndCtl ) 1047 1388 { 1048 DialogBoxParam(hResInst,MAKEINTRESOURCE(IDD_STRING_COUNT),m_hWnd, (DLGPROC)DlgStringCount,0);1389 DialogBoxParam(hResInst,MAKEINTRESOURCE(IDD_STRING_COUNT),m_hWnd,DlgStringCount,0); 1049 1390 } 1050 1391 1051 1392 void MainFrame::OnCmdSelStringCount( UINT uNotifyCode, int nID, CWindow wndCtl ) 1052 1393 { 1053 DialogBoxParam(hResInst,MAKEINTRESOURCE(IDD_STRING_COUNT),m_hWnd, (DLGPROC)DlgStringCount,1);1394 DialogBoxParam(hResInst,MAKEINTRESOURCE(IDD_STRING_COUNT),m_hWnd,DlgStringCount,1); 1054 1395 } 1055 1396 #endif … … 1290 1631 int idProcess; 1291 1632 DWORD dwPlatform; 1292 idProcess=DialogBoxParam(hResInst,MAKEINTRESOURCE(IDD_ATTACH),m_hWnd, (DLGPROC)DlgAttach,(LPARAM)&dwPlatform);1633 idProcess=DialogBoxParam(hResInst,MAKEINTRESOURCE(IDD_ATTACH),m_hWnd,DlgAttach,(LPARAM)&dwPlatform); 1293 1634 if(idProcess==0) return; 1294 1635 … … 1552 1893 void MainFrame::OnCmdAbout( UINT uNotifyCode, int nID, CWindow wndCtl ) 1553 1894 { 1554 DialogBox(hResInst,MAKEINTRESOURCE(IDD_ABOUT),m_hWnd, (DLGPROC)DialogAbout);1895 DialogBox(hResInst,MAKEINTRESOURCE(IDD_ABOUT),m_hWnd,DialogAbout); 1555 1896 } 1556 1897 … … 1611 1952 //このウィンドウ以外をすべて閉じる(&A) 1612 1953 HWND hChild=::GetWindow(hClient,GW_CHILD); 1613 int WndNum=GetWndNum(hChild); 1614 for(int i=0;i<MdiInfo.size();i++){ 1615 if(i==WndNum) continue; 1616 if(MdiInfo[i]->hwnd) SendMessage(MdiInfo[i]->hwnd,WM_CLOSE,0,0); 1954 foreach ( MDIINFO *mi, MdiInfo ){ 1955 if ( mi->hwnd == hChild ){ 1956 continue; 1957 } 1958 if(mi->hwnd){ 1959 ::PostMessage( mi->hwnd, WM_CLOSE, 0, 0 ); 1960 //foreachの最中に削除されるとイテレータが回らないのでSendを使っていない。 1961 } 1617 1962 } 1618 1963 }
Note:
See TracChangeset
for help on using the changeset viewer.