OSDN Git Service

dd97d8b94b9177553450fc8e9a3adf4c3377b373
[winmerge-jp/winmerge-jp.git] / Src / WindowsManagerDialog.cpp
1 // WindowsManagerDialog.cpp : implementation file
2 //
3
4 #include "stdafx.h"
5 #include "Merge.h"
6 #include "WindowsManagerDialog.h"
7
8 #ifdef _DEBUG
9 #define new DEBUG_NEW
10 #undef THIS_FILE
11 static char THIS_FILE[] = __FILE__;
12 #endif
13
14 /////////////////////////////////////////////////////////////////////////////
15 // CWindowsManagerDialog dialog
16
17 CWindowsManagerDialog::CWindowsManagerDialog(CWnd* pParent/* = NULL*/)
18         : CDialog(CWindowsManagerDialog::IDD, pParent)
19         ,m_bAutoCleanup(FALSE)
20         ,m_pFrame(NULL)
21         ,m_pIL(NULL)
22 {
23         //{{AFX_DATA_INIT(CWindowsManagerDialog)
24                 // NOTE: the ClassWizard will add member initialization here
25         //}}AFX_DATA_INIT
26 }
27
28 CWindowsManagerDialog::~CWindowsManagerDialog()
29 {
30         if (NULL != m_pIL->GetSafeHandle())
31                 m_pIL->DeleteImageList();
32         if (NULL != m_pIL)
33                 delete m_pIL;
34 }
35
36 void CWindowsManagerDialog::DoDataExchange(CDataExchange* pDX)
37 {
38         CDialog::DoDataExchange(pDX);
39         //{{AFX_DATA_MAP(CWindowsManagerDialog)
40         // NOTE: the ClassWizard will add DDX and DDV calls here
41         //}}AFX_DATA_MAP
42         DDX_Control(pDX, IDC_LIST_FILE, m_List);
43 }
44
45 BEGIN_MESSAGE_MAP(CWindowsManagerDialog, CDialog)
46         //{{AFX_MSG_MAP(CWindowsManagerDialog)
47         ON_WM_SIZE()
48         ON_WM_CLOSE()
49         ON_WM_ACTIVATE()
50         ON_WM_DESTROY()
51         ON_NOTIFY(NM_CUSTOMDRAW, IDC_LIST_FILE, &CWindowsManagerDialog::OnNMCustomdrawListFile)
52         ON_NOTIFY(NM_DBLCLK, IDC_LIST_FILE, &CWindowsManagerDialog::OnNMDblclkListFile)
53         //}}AFX_MSG_MAP
54         ON_MESSAGE(WMU_ISOPEN, &CWindowsManagerDialog::OnIsOpen)
55         ON_MESSAGE(WMU_SELECTNEXT, &CWindowsManagerDialog::OnSelectNext)
56 END_MESSAGE_MAP()
57
58 /////////////////////////////////////////////////////////////////////////////
59 // CWindowsManagerDialog message handlers
60
61 BOOL CWindowsManagerDialog::PreTranslateMessage(MSG* pMsg)
62 {
63         if ((WM_KEYUP == pMsg->message && VK_CONTROL == pMsg->wParam) || 
64                 (WM_KEYDOWN == pMsg->message && VK_ESCAPE == pMsg->wParam))
65         {
66                 PostMessage(WM_CLOSE);
67         }
68
69         if (WM_KEYDOWN == pMsg->message && VK_TAB == pMsg->wParam)
70         {
71                 PostMessage(WMU_SELECTNEXT, (GetAsyncKeyState(VK_SHIFT) < 0) ? 1 : 0, 0);
72         }
73
74         return CDialog::PreTranslateMessage(pMsg);
75 }
76
77 BOOL CWindowsManagerDialog::OnInitDialog()
78 {
79         CDialog::OnInitDialog();
80
81         m_List.SetExtendedStyle(LVS_EX_INFOTIP | LVS_EX_FULLROWSELECT);
82
83         if (NULL == m_pIL)
84                 m_pIL = new CImageList();
85
86         m_pIL->DeleteImageList();
87         m_pIL->Create(16, 16, ILC_COLOR32 | ILC_MASK, 0, 1);
88         m_List.SetImageList(m_pIL, LVSIL_SMALL);
89         m_List.SetBkColor(WMD_LISTCOLOR_BKG);
90         m_List.SetTextBkColor(WMD_LISTCOLOR_BKG);
91
92         PopulateList();
93
94         if(m_List.GetItemCount() > 0)
95                 m_List.SetItemState((1 == m_List.GetItemCount()) ? 0 : 1, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
96
97         AdjustSize();
98         CenterWindow(m_pFrame); // please initialize the parent window before creating dialog
99
100         return TRUE;  // return TRUE unless you set the focus to a control
101                                   // EXCEPTION: OCX Property Pages should return FALSE
102 }
103
104 void CWindowsManagerDialog::PopulateList()
105 {
106         if (m_List.GetItemCount() <= 0)
107         {
108                 CRect rect;
109                 m_List.GetWindowRect(rect);
110                 m_List.InsertColumn(0, _T("Files"), LVCFMT_LEFT, rect.Width());
111         }
112
113         m_List.DeleteAllItems();
114
115         CString sText;
116         const CTypedPtrArray<CPtrArray, CMDIChildWnd*>* pArrChild = m_pFrame->GetChildArray();
117         for (int i = 0; i < pArrChild->GetSize(); ++i)
118         {
119                 HICON hIcon = pArrChild->GetAt(i)->GetIcon(TRUE);
120                 if (NULL == hIcon)
121                         hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
122                 m_pIL->Add(hIcon);
123                 sText = pArrChild->GetAt(i)->GetActiveDocument()->GetPathName();
124                 if(sText.IsEmpty())
125                         pArrChild->GetAt(i)->GetWindowText(sText);
126                 m_List.InsertItem(i, sText, m_pIL->GetImageCount() - 1);
127                 m_List.SetItemData(i, (DWORD_PTR)pArrChild->GetAt(i));
128         }
129 }
130 // adjust size to listctrl column and dialog
131 void CWindowsManagerDialog::AdjustSize()
132 {
133         CRect rect;
134         m_List.GetItemRect(0, rect, LVIR_ICON);
135
136         const int nImgWidth = rect.right - rect.left;
137         const int nSpaceWidth = m_List.GetStringWidth(_T(" "));
138         const int nLeftMargin = ::GetSystemMetrics(SM_CXFRAME) * 2 + nSpaceWidth * 4;
139
140         int nMaxWidth = -1;
141
142         CString sText;
143         CRect _rc(0, 0, 0, 0);
144         for (int i = 0; i < m_List.GetItemCount(); ++i)
145         {
146                 sText = m_List.GetItemText(i, 0);
147                 int nWidth = m_List.GetStringWidth(sText);
148                 if (nWidth > nMaxWidth)
149                         nMaxWidth = nWidth;
150                 _rc.bottom += rect.bottom - rect.top;
151         }
152
153         _rc.right = nMaxWidth + nImgWidth + nLeftMargin + 2 * ::GetSystemMetrics(SM_CYVSCROLL);
154         m_List.SetColumnWidth(0, _rc.right - ::GetSystemMetrics(SM_CYFRAME));
155
156         //if the tasklist exceeds the height of the display, leave some space at the bottom
157         if (_rc.bottom > ::GetSystemMetrics(SM_CYSCREEN) - 50)
158         {
159                 _rc.bottom = ::GetSystemMetrics(SM_CYSCREEN) - 50;
160                 m_List.SetColumnWidth(0, _rc.right - ::GetSystemMetrics(SM_CYFRAME) - ::GetSystemMetrics(SM_CYVSCROLL));
161         }
162         // Task List's border is 1px smaller than ::GetSystemMetrics(SM_CYFRAME) returns
163         _rc.bottom += ::GetSystemMetrics(SM_CYFRAME);
164         MoveWindow(_rc, FALSE);
165 }
166
167 void CWindowsManagerDialog::SetParentWnd(CWnd* pWnd)
168 {
169         ASSERT(NULL != pWnd);
170         m_pFrame = DYNAMIC_DOWNCAST(CMainFrame, pWnd);
171 }
172
173 void CWindowsManagerDialog::OnSize(UINT nType, int cx, int cy)
174 {
175         CDialog::OnSize(nType, cx, cy);
176
177         if(NULL != m_List.GetSafeHwnd() && cx > 0 && cy > 0)
178                 m_List.MoveWindow(0, 0, cx, cy);
179 }
180
181 void CWindowsManagerDialog::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized)
182 {
183         CDialog::OnActivate(nState, pWndOther, bMinimized);
184
185         if (WA_INACTIVE == nState)
186                 PostMessage(WM_CLOSE);
187 }
188
189 void CWindowsManagerDialog::OnClose()
190 {
191         if (m_bAutoCleanup)
192                 DestroyWindow();
193         else
194                 CDialog::OnClose();
195 }
196
197 void CWindowsManagerDialog::OnOK()
198 {
199         if (m_bAutoCleanup)
200                 DestroyWindow();
201         else
202                 CDialog::OnOK();
203 }
204
205 void CWindowsManagerDialog::OnCancel()
206 {
207         if (m_bAutoCleanup)
208                 DestroyWindow();
209         else
210                 CDialog::OnCancel();
211 }
212
213 void CWindowsManagerDialog::PostNcDestroy()
214 {
215         CDialog::PostNcDestroy();
216
217         if (m_bAutoCleanup)
218                 delete this;
219 }
220
221 void CWindowsManagerDialog::OnDestroy()
222 {
223         CDialog::OnDestroy();
224
225         const int nIndex = m_List.GetNextItem(-1, LVNI_SELECTED);
226         if (nIndex >= 0 && nIndex < m_List.GetItemCount())
227                 ::PostMessage(AfxGetMainWnd()->GetSafeHwnd(), WMU_CHILDFRAMEACTIVATE, 0, (LPARAM)m_List.GetItemData(nIndex));
228 }
229
230 LRESULT CWindowsManagerDialog::OnIsOpen(WPARAM wParam, LPARAM lParam)
231 {
232         return 1;
233 }
234
235 LRESULT CWindowsManagerDialog::OnSelectNext(WPARAM wParam, LPARAM lParam)
236 {
237         int nIndex = m_List.GetNextItem(-1, LVNI_SELECTED);
238         if (wParam)             // reverse order
239         {
240                 if (0 == nIndex)
241                         nIndex = m_List.GetItemCount() - 1;
242                 else
243                         nIndex--;
244         }
245         else
246         {
247                 if (nIndex == m_List.GetItemCount() - 1)
248                         nIndex = 0;
249                 else
250                         nIndex++;
251         }
252
253         m_List.SetItemState(nIndex, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
254         m_List.EnsureVisible(nIndex, FALSE);
255
256         return 1;
257 }
258
259 void CWindowsManagerDialog::OnNMCustomdrawListFile(NMHDR* pNMHDR, LRESULT* pResult)
260 {
261         NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>(pNMHDR);
262
263         switch (pLVCD->nmcd.dwDrawStage)
264         {
265         case CDDS_PREPAINT:
266                 *pResult = CDRF_NOTIFYITEMDRAW;
267                 break;
268         case CDDS_ITEMPREPAINT:
269                 if (CDIS_FOCUS == (pLVCD->nmcd.uItemState & CDIS_FOCUS))
270                 {
271                         pLVCD->nmcd.uItemState = CDIS_DEFAULT;
272                         pLVCD->clrTextBk = WMD_LISTCOLOR_BKGSEL;
273                 }
274                 *pResult = CDRF_DODEFAULT;
275                 break;
276         default:
277                 *pResult = CDRF_DODEFAULT;
278                 break;
279         }
280 }
281
282 void CWindowsManagerDialog::OnNMDblclkListFile(NMHDR* pNMHDR, LRESULT* pResult)
283 {
284         *pResult = 0;
285
286         PostMessage(WM_CLOSE);
287 }