Index: trunk/ab5.0/abdev/abdev/src/MainFrame.cpp
===================================================================
--- trunk/ab5.0/abdev/abdev/src/MainFrame.cpp	(revision 749)
+++ trunk/ab5.0/abdev/abdev/src/MainFrame.cpp	(revision 772)
@@ -10,5 +10,5 @@
 void CreateProcessWithStdHandle( const std::string &appPath, const std::string &cmdLine, bool isShowWindow = true )
 {
-	std::string argsStr = "\"" + appPath + "\" " + cmdLine;
+	std::string argsStr = '\"' + appPath + "\" " + cmdLine;
 	STARTUPINFO si;
 	PROCESS_INFORMATION pi;
@@ -21,11 +21,316 @@
 	si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
 	
-	char args[8192];
-	lstrcpy( args, argsStr.c_str() );
-
-	CreateProcess( NULL, args, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi );
+	std::vector<char> args( argsStr.c_str(), argsStr.c_str() + argsStr.size() + 1 );
+
+	CreateProcess( NULL, &args[0], NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi );
 	CloseHandle( pi.hProcess );
 	CloseHandle( pi.hThread );
 }
+
+#ifdef HAVE_WINDOWS_7_SDK
+
+#define MSGFLT_ADD 1
+
+#pragma push_macro("_WIN32_WINNT")
+#undef _WIN32_WINNT
+#define _WIN32_WINNT 0x0601
+#include <dwmapi.h>
+#pragma pop_macro("_WIN32_WINNT")
+
+#define WM_DWMSENDICONICTHUMBNAIL 0x0323
+#define WM_DWMSENDICONICLIVEPREVIEWBITMAP 0x0326
+
+// Windows 7タスクバーにボタンとして表示させるためのウィンドウ。
+// 各MDI子ウィンドウ (wndTarget) と1対1に対応する。
+class DummyWindowForTaskbarButton : public ATL::CWindowImpl<DummyWindowForTaskbarButton>, boost::noncopyable
+{
+public:
+	DECLARE_WND_CLASS(TEXT("DummyWindow For Taskbar Button"));
+
+	BEGIN_MSG_MAP(DummyWindowForTaskbarButton)
+		MESSAGE_HANDLER_EX(WM_DWMSENDICONICTHUMBNAIL, OnDwmSendIconicThumnail)
+		MESSAGE_HANDLER_EX(WM_DWMSENDICONICLIVEPREVIEWBITMAP, OnDwmSendIconicLivePreviewBitmap)
+		MSG_WM_ACTIVATE(OnActivate)
+	END_MSG_MAP()
+
+	explicit DummyWindowForTaskbarButton(HWND hwndTarget, const char* title) :
+		wndTarget(hwndTarget)
+	{
+		HWND hwndDummy = Create( hOwner, CRect( -32000, -32000, 1, 1 ), title,
+			WS_BORDER | WS_SYSMENU | WS_CAPTION, WS_EX_NOACTIVATE);
+		SetIcon( wndTarget.GetIcon( FALSE ), FALSE );
+		SetIcon( wndTarget.GetIcon( TRUE ), TRUE );
+
+		BOOL iconicRepresentation = TRUE;
+		HRESULT hr;
+		hr = DwmSetWindowAttribute(
+			*this,
+			DWMWA_FORCE_ICONIC_REPRESENTATION,
+			&iconicRepresentation,
+			sizeof iconicRepresentation);
+		BOOL iconicBitmap = TRUE;
+		hr = DwmSetWindowAttribute(
+			*this,
+			DWMWA_HAS_ICONIC_BITMAP,
+			&iconicBitmap,
+			sizeof iconicBitmap);
+	}
+
+	~DummyWindowForTaskbarButton()
+	{
+	}
+private:
+	void OnActivate(UINT state, BOOL /*minimized*/, HWND /*hwndOther*/)
+	{
+		if (state == WA_ACTIVE)
+		{
+			if (ActiveBasic::IDE::Program::mainFrame.IsIconic())
+			{
+				ActiveBasic::IDE::Program::mainFrame.ShowWindow(SW_RESTORE);
+			}
+			SetForegroundWindow(ActiveBasic::IDE::Program::mainFrame);
+			ActiveBasic::IDE::Program::mainFrame.MDIActivate(wndTarget);
+			wndTarget.Invalidate(FALSE);
+		}
+	}
+
+	class BitmapMemoryDC : public WTL::CDC, boost::noncopyable
+	{
+	public:
+		explicit BitmapMemoryDC(HBITMAP hbmp) :
+			WTL::CDC(::CreateCompatibleDC(0)),
+			bmp(hbmp),
+			hbmpOld(SelectBitmap(bmp))
+		{
+		}
+		BitmapMemoryDC(int width, int height, void*& bits) :
+			WTL::CDC(::CreateCompatibleDC(0)),
+			bmp(CreateDIBSection32(m_hDC, width, height, bits)),
+			hbmpOld(SelectBitmap(bmp))
+		{
+		}
+		~BitmapMemoryDC()
+		{
+			SelectBitmap(hbmpOld); // この後、CDCとbmpのデストラクタでそれぞれDeleteDCとDeleteObjectがなされる。
+		}
+		WTL::CBitmap& GetBitmap()
+		{
+			return bmp;
+		}
+	private:
+		WTL::CBitmap bmp;
+		HBITMAP hbmpOld;
+	};
+
+	LRESULT OnDwmSendIconicThumnail(UINT, WPARAM, LPARAM lp)
+	{
+		HRESULT hr = SetIconicThumbnail(HIWORD(lp), LOWORD(lp));
+		return 0;
+	}
+
+	LRESULT OnDwmSendIconicLivePreviewBitmap(UINT, WPARAM, LPARAM)
+	{
+		HRESULT hr = SetIconicLivePreviewBitmap();
+		return 0;
+	}
+
+	HRESULT SetIconicThumbnail(int maximumWidth, int maximumHeight)
+	{
+		int widthBmp, heightBmp;
+		BitmapMemoryDC dcSrc(CreateBitmap(widthBmp, heightBmp));
+		if (dcSrc)
+		{
+			int width, height;  // dcSrcの縦横比に合わせて縮小する
+			if (widthBmp * maximumHeight > maximumWidth * heightBmp) // (widthBmp / heightBmp > maximumWidth / maximumHeight)
+			{
+				width = maximumWidth;
+				height = heightBmp * maximumWidth / widthBmp;
+			}
+			else
+			{
+				height = maximumHeight;
+				width = widthBmp * maximumHeight / heightBmp;
+			}
+			void* pvBits;
+			BitmapMemoryDC dc(width, height, pvBits);
+			if (dc)
+			{
+				StretchBlt(dc, 0, 0, width, height, dcSrc, 0, 0, widthBmp, heightBmp, SRCCOPY);
+				return DwmSetIconicThumbnail(*this, dc.GetBitmap(), DWM_SIT_DISPLAYFRAME);
+			}
+		}
+		return HRESULT_FROM_WIN32(GetLastError());
+	}
+
+	HRESULT SetIconicLivePreviewBitmap()
+	{
+		int w, h;
+		WTL::CBitmap bmp(CreateBitmap(w, h));
+		if (bmp)
+		{
+			POINT pt = {};
+			wndTarget.MapWindowPoints(hOwner, &pt, 1);
+			pt.y += GetSystemMetrics(SM_CYMENU);
+			return DwmSetIconicLivePreviewBitmap(*this, bmp, &pt, wndTarget.IsZoomed() ? 0 : DWM_SIT_DISPLAYFRAME);
+		}
+		return HRESULT_FROM_WIN32(GetLastError());
+	}
+
+	static void SetAlpha(DWORD& pixel)
+	{
+		pixel |= 0xff000000;
+	}
+
+	HBITMAP CreateBitmap(int& width, int& height)
+	{
+		RECT rcClient;
+		wndTarget.GetClientRect(&rcClient);
+		void* pvBits;
+		BitmapMemoryDC dc(rcClient.right, rcClient.bottom, pvBits);
+		if (dc)
+		{
+			int wndNum = GetWndNum(wndTarget);
+			if (wndNum != -1)
+			{
+				CPoint origin(0, 0);
+				wndTarget.ClientToScreen( &origin );
+				CRect rcWindow;
+				wndTarget.GetWindowRect( rcWindow );
+				origin -= rcWindow.TopLeft();
+				dc.SetWindowOrg( origin ); // クライアント領域の(0, 0)がビットマップの(0, 0)になるよう合わせる
+				wndTarget.Print( dc, PRF_CHECKVISIBLE | PRF_ERASEBKGND | PRF_CHILDREN | PRF_CLIENT );
+				width = rcClient.right;
+				height = rcClient.bottom;
+				DWORD* pdwBits = static_cast<DWORD*>(pvBits);
+				std::for_each(pdwBits, pdwBits + width * height, SetAlpha);
+				return dc.GetBitmap().Detach();
+			}
+		}
+		return 0;
+	}
+	// 32ビットトップダウンのDIBセクションを作る補助
+	static HBITMAP CreateDIBSection32(HDC hdc, int width, int height, void*& pb)
+	{
+		BITMAPINFO bi;
+		ZeroMemory(&bi.bmiHeader, sizeof bi.bmiHeader);
+		bi.bmiHeader.biSize = sizeof bi.bmiHeader;
+		bi.bmiHeader.biWidth = width;
+		bi.bmiHeader.biHeight = -height;  // トップダウンDIBにする必要があるらしい
+		bi.bmiHeader.biPlanes = 1;
+		bi.bmiHeader.biBitCount = 32;
+		return CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, &pb, 0, 0);
+	}
+
+	CWindow wndTarget;
+};
+
+class TaskbarList
+{
+	typedef boost::shared_ptr<DummyWindowForTaskbarButton> DummyWindowForTaskbarButtonPtr;
+	typedef std::map<HWND, DummyWindowForTaskbarButtonPtr> WindowMap;
+public:
+	TaskbarList(HWND hwndFrame) :
+		wndFrame(hwndFrame)
+	{
+		HRESULT hr = taskbarList.CoCreateInstance( CLSID_TaskbarList );
+		if ( FAILED( hr ) ) {
+			return;
+		}
+		HRESULT hr2 = taskbarList->HrInit();
+		if ( FAILED( hr2 ) ) {
+			taskbarList.Release();
+			return;
+		}
+	}
+
+	void RegisterTab(HWND hwndChild, const char* title)
+	{
+		assert( hwndChild );
+		if (taskbarList)
+		{
+			assert( windowMap.find(hwndChild) == windowMap.end() );
+			DummyWindowForTaskbarButtonPtr p(new DummyWindowForTaskbarButton(hwndChild, title));
+			windowMap.insert(std::make_pair(hwndChild, p));
+			//タスクバーボタンに追加
+			HRESULT hr = taskbarList->RegisterTab(*p, wndFrame);
+		}
+	}
+
+	void RegisterTab(HWND hwndChild)
+	{
+		ATL::CWindow wnd = hwndChild;
+		ATL::CString title;
+		wnd.GetWindowText(title);
+		RegisterTab(hwndChild, title);
+	}
+
+	void UnregisterTab(HWND hwndChild)
+	{
+		if (taskbarList)
+		{
+			WindowMap::iterator it = windowMap.find(hwndChild);
+			assert( it != windowMap.end() );
+			HRESULT hr = taskbarList->UnregisterTab(*it->second);
+			it->second->DestroyWindow();
+			windowMap.erase( it );
+		}
+	}
+
+	void InvalidateIconicBitmaps(HWND hwndChild)
+	{
+		DwmInvalidateIconicBitmaps(*mapAt(hwndChild));
+	}
+
+	void SetTabActivate(HWND hwndChild)
+	{
+		if (taskbarList)
+		{
+			taskbarList->SetTabActive(*mapAt(hwndChild), wndFrame, 0);
+		}
+	}
+
+	void SetTabOrder( HWND hwndChild, HWND hwndInsertBefore )
+	{
+		if (taskbarList)
+		{
+		taskbarList->SetTabOrder(*mapAt(hwndChild),
+			hwndInsertBefore
+			? static_cast<HWND>(*mapAt(hwndInsertBefore))
+			: 0);
+		}
+	}
+private:
+	DummyWindowForTaskbarButtonPtr mapAt(HWND hwndChild)
+	{
+		DummyWindowForTaskbarButtonPtr p = windowMap[hwndChild];
+		assert(p);
+		return p;
+	}
+	CWindow wndFrame;
+	ATL::CComPtr<ITaskbarList3> taskbarList;
+	WindowMap windowMap;
+};
+#endif HAVE_WINDOWS_7_SDK
+
+#ifdef HAVE_WINDOWS_7_SDK
+MainFrame::MainFrame() :
+	TaskbarButtonCreated( RegisterWindowMessage( TEXT("TaskbarButtonCreated") ) )
+{
+	if ( TaskbarButtonCreated != 0 )
+	{
+		typedef BOOL WINAPI CWMF(UINT, DWORD);
+		HMODULE hmodUser = GetModuleHandle( TEXT("user32.dll") );
+		assert( hmodUser != 0 );
+		if ( CWMF* pcwmf = reinterpret_cast<CWMF*>( GetProcAddress( hmodUser, "ChangeWindowMessageFilter" ) ) )
+		{
+			pcwmf(TaskbarButtonCreated, MSGFLT_ADD);
+			pcwmf(WM_DWMSENDICONICTHUMBNAIL, MSGFLT_ADD);
+			pcwmf(WM_DWMSENDICONICLIVEPREVIEWBITMAP, MSGFLT_ADD);
+		}
+	}
+}
+#else
+MainFrame::MainFrame() {}
+#endif
 
 void MainFrame::Resized()
@@ -59,5 +364,5 @@
 	//Status bar
 	int height_Statusbar;
-	SendMessage(hStatusBar,SB_GETRECT,0,(long)&StatusRect);
+	SendMessage(hStatusBar,SB_GETRECT,0,(LPARAM)&StatusRect);
 	height_Statusbar=StatusRect.bottom;
 
@@ -227,6 +532,5 @@
 	hOwner = m_hWnd;
 	extern WNDPROC oldMainFrameWndProc;
-	oldMainFrameWndProc = (WNDPROC)::GetWindowLong( hOwner, GWL_WNDPROC );
-	::SetWindowLongPtr( hOwner, GWL_WNDPROC, reinterpret_cast<LONG_PTR>(WindowFunc) );
+	oldMainFrameWndProc = (WNDPROC)::SetWindowLongPtr( hOwner, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(WindowFunc) );
 
 	SetupWindow(hOwner);
@@ -234,6 +538,4 @@
 	//テキストエディタフォント設定
 	ResetTextEditFont(hOwner);
-
-
 
 	return 0;
@@ -549,17 +851,10 @@
 void MainFrame::OnPaint( HDC )
 {
-	PAINTSTRUCT ps;
-	HDC hdc = this->BeginPaint( &ps );
-
-	HBRUSH hBrush = CreateSolidBrush( GetSysColor( COLOR_3DFACE ) );
+	WTL::CPaintDC dc( m_hWnd );
 
 	RECT rect;
 	this->GetClientRect( &rect );
 
-	FillRect( hdc, &rect, hBrush );
-
-	DeleteObject( hBrush );
-
-	this->EndPaint( &ps );
+	dc.FillRect( &rect, GetSysColorBrush( COLOR_3DFACE ) );
 }
 
@@ -600,5 +895,5 @@
 	::UpdateWindow(hChild);
 
-	char *pTemp=MdiInfo[WndNum]->pMdiTextEdit->buffer;
+	const char *pTemp=MdiInfo[WndNum]->pMdiTextEdit->buffer;
 
 	//行の先頭インデックスを取得（取得する行の番号はwParamで渡される）
@@ -628,4 +923,50 @@
 }
 
+::LRESULT MainFrame::OnTaskbarButtonCreated( ::UINT msg, ::WPARAM, ::LPARAM )
+{
+#ifdef HAVE_WINDOWS_7_SDK
+	if ( msg == 0 ) { // 念のため確認
+		return 0;
+	}
+	taskbarList.reset(new TaskbarList(*this));
+#endif
+	return 0;
+}
+
+void MainFrame::AddChildWindow( HWND hwndChild )
+{
+#ifdef HAVE_WINDOWS_7_SDK
+	taskbarList->RegisterTab( hwndChild );
+#endif
+}
+
+void MainFrame::DeleteChildWindow( HWND hwndChild )
+{
+#ifdef HAVE_WINDOWS_7_SDK
+	taskbarList->UnregisterTab( hwndChild );
+#endif
+}
+
+void MainFrame::ActivateChildWindow( HWND hwndChild )
+{
+#ifdef HAVE_WINDOWS_7_SDK
+	taskbarList->SetTabActivate( hwndChild );
+#endif
+}
+
+void MainFrame::SetTabOrder( HWND hwndChild, HWND hwndInsertBefore )
+{
+#ifdef HAVE_WINDOWS_7_SDK
+	taskbarList->SetTabOrder( hwndChild, hwndInsertBefore );
+#endif
+}
+
+void MainFrame::InvalidateBitmap( HWND hwndChild )
+{
+#ifdef HAVE_WINDOWS_7_SDK
+	taskbarList->InvalidateIconicBitmaps( hwndChild );
+#endif
+}
+
 void MainFrame::OnCmdNew( UINT uNotifyCode, int nID, CWindow wndCtl )
 {
@@ -639,5 +980,5 @@
 	char temporary[MAX_PATH];
 
-	FileType=DialogBox(hResInst,MAKEINTRESOURCE(IDD_NEWFILE),hOwner,(DLGPROC)DlgNewFile);
+	FileType=DialogBox(hResInst,MAKEINTRESOURCE(IDD_NEWFILE),hOwner,DlgNewFile);
 	if(FileType==-1) return;
 
@@ -745,11 +1086,11 @@
 {
 	//文字コードを指定して保存
-	DialogBox(hResInst,MAKEINTRESOURCE(IDD_CODE_SAVE),m_hWnd,(DLGPROC)nkfDlgCodeSave);
+	DialogBox(hResInst,MAKEINTRESOURCE(IDD_CODE_SAVE),m_hWnd,nkfDlgCodeSave);
 }
 
 void MainFrame::OnCmdAllSave( UINT uNotifyCode, int nID, CWindow wndCtl )
 {
-	for( int i=0;i<MdiInfo.size();i++){
-		if(MdiInfo[i]->hwnd) SaveDocument(MdiInfo[i]->hwnd,NULL);
+	foreach( MDIINFO *mi, MdiInfo ){
+		if(mi->hwnd) SaveDocument(mi->hwnd,NULL);
 	}
 	if( projectInfo.IsOpened() )
@@ -824,5 +1165,5 @@
 		TextEdit_GetSel(WndNum,&CharRange);
 
-		HGLOBAL hGlobal=(char *)GlobalAlloc(GMEM_MOVEABLE,CharRange.cpMax-CharRange.cpMin+1);
+		HGLOBAL hGlobal=GlobalAlloc(GMEM_MOVEABLE,CharRange.cpMax-CharRange.cpMin+1);
 		char *pTemp=(char *)GlobalLock(hGlobal);
 		memcpy(pTemp,MdiInfo[WndNum]->pMdiTextEdit->buffer+CharRange.cpMin,CharRange.cpMax-CharRange.cpMin);
@@ -885,5 +1226,5 @@
 		TextEdit_GetSel(WndNum,&CharRange);
 
-		HGLOBAL hGlobal=(char *)GlobalAlloc(GMEM_MOVEABLE,CharRange.cpMax-CharRange.cpMin+1);
+		HGLOBAL hGlobal=GlobalAlloc(GMEM_MOVEABLE,CharRange.cpMax-CharRange.cpMin+1);
 		char *pTemp=(char *)GlobalLock(hGlobal);
 		memcpy(pTemp,MdiInfo[WndNum]->pMdiTextEdit->buffer+CharRange.cpMin,CharRange.cpMax-CharRange.cpMin);
@@ -1030,10 +1371,10 @@
 void MainFrame::OnCmdFind( UINT uNotifyCode, int nID, CWindow wndCtl )
 {
-	DialogBox(hResInst,MAKEINTRESOURCE(IDD_FIND),m_hWnd,(DLGPROC)DlgFind);
+	DialogBox(hResInst,MAKEINTRESOURCE(IDD_FIND),m_hWnd,DlgFind);
 }
 
 void MainFrame::OnCmdPermutation( UINT uNotifyCode, int nID, CWindow wndCtl )
 {
-	DialogBox(hResInst,MAKEINTRESOURCE(IDD_PERMUTATION),m_hWnd,(DLGPROC)DlgPermutation);
+	DialogBox(hResInst,MAKEINTRESOURCE(IDD_PERMUTATION),m_hWnd,DlgPermutation);
 }
 
@@ -1046,10 +1387,10 @@
 void MainFrame::OnCmdStringCount( UINT uNotifyCode, int nID, CWindow wndCtl )
 {
-	DialogBoxParam(hResInst,MAKEINTRESOURCE(IDD_STRING_COUNT),m_hWnd,(DLGPROC)DlgStringCount,0);
+	DialogBoxParam(hResInst,MAKEINTRESOURCE(IDD_STRING_COUNT),m_hWnd,DlgStringCount,0);
 }
 
 void MainFrame::OnCmdSelStringCount( UINT uNotifyCode, int nID, CWindow wndCtl )
 {
-	DialogBoxParam(hResInst,MAKEINTRESOURCE(IDD_STRING_COUNT),m_hWnd,(DLGPROC)DlgStringCount,1);
+	DialogBoxParam(hResInst,MAKEINTRESOURCE(IDD_STRING_COUNT),m_hWnd,DlgStringCount,1);
 }
 #endif
@@ -1290,5 +1631,5 @@
 	int idProcess;
 	DWORD dwPlatform;
-	idProcess=DialogBoxParam(hResInst,MAKEINTRESOURCE(IDD_ATTACH),m_hWnd,(DLGPROC)DlgAttach,(LPARAM)&dwPlatform);
+	idProcess=DialogBoxParam(hResInst,MAKEINTRESOURCE(IDD_ATTACH),m_hWnd,DlgAttach,(LPARAM)&dwPlatform);
 	if(idProcess==0) return;
 
@@ -1552,5 +1893,5 @@
 void MainFrame::OnCmdAbout( UINT uNotifyCode, int nID, CWindow wndCtl )
 {
-	DialogBox(hResInst,MAKEINTRESOURCE(IDD_ABOUT),m_hWnd,(DLGPROC)DialogAbout);
+	DialogBox(hResInst,MAKEINTRESOURCE(IDD_ABOUT),m_hWnd,DialogAbout);
 }
 
@@ -1611,8 +1952,12 @@
 	//このウィンドウ以外をすべて閉じる(&A)
 	HWND hChild=::GetWindow(hClient,GW_CHILD);
-	int WndNum=GetWndNum(hChild);
-	for(int i=0;i<MdiInfo.size();i++){
-		if(i==WndNum) continue;
-		if(MdiInfo[i]->hwnd) SendMessage(MdiInfo[i]->hwnd,WM_CLOSE,0,0);
+	foreach ( MDIINFO *mi, MdiInfo ){
+		if ( mi->hwnd == hChild ){
+			continue;
+		}
+		if(mi->hwnd){
+			::PostMessage( mi->hwnd, WM_CLOSE, 0, 0 );
+			//foreachの最中に削除されるとイテレータが回らないのでSendを使っていない。
+		}
 	}
 }
Index: trunk/ab5.0/abdev/abdev/src/Program.cpp
===================================================================
--- trunk/ab5.0/abdev/abdev/src/Program.cpp	(revision 749)
+++ trunk/ab5.0/abdev/abdev/src/Program.cpp	(revision 772)
@@ -17,5 +17,5 @@
 	// メインフレームを作成
 	mainFrame.Create(
-		HWND_DESKTOP,
+		0,
 		pobj_nv->StartupWindowRect,
 		APPLICATION_NAME,
@@ -32,7 +32,7 @@
 }
 
-void Program::Main()
+void Program::Main(HINSTANCE hinst)
 {
-	_Module.Init( NULL, GetModuleHandle( NULL ) );
+	_Module.Init( NULL, hinst );
 
     CMessageLoop loop;
