LRESULT CVideoMarkup::OnBeginDrag(int idCtrl, LPNMHDR pnmh, BOOL&) { POINT p; HIMAGELIST hImageListSingle, hImageListMerged; int numSelected = ListView_GetSelectedCount(m_sampleListView); int iSelection = -1; for (int iIndex=0; iIndex<numSelected; iIndex++) { iSelection = ListView_GetNextItem(m_sampleListView, iSelection, LVNI_SELECTED); if (iIndex == 0) { // first selected icon hDragImageList = ListView_CreateDragImage(m_sampleListView, iSelection, &p); } else { // subsequent icons hImageListSingle = ListView_CreateDragImage(m_sampleListView, iSelection, &p); hImageListMerged = ImageList_Merge(hDragImageList, 0, hImageListSingle, 0, iIndex*3, iIndex*3); ImageList_Destroy(hDragImageList); ImageList_Destroy(hImageListSingle); hDragImageList = hImageListMerged; } } ImageList_BeginDrag(hDragImageList, 0, LISTVIEW_SAMPLE_X/2, LISTVIEW_SAMPLE_Y/2); POINT pt = ((NM_LISTVIEW*)pnmh)->ptAction; RECT listViewRect; m_sampleListView.GetClientRect(&listViewRect); m_sampleListView.ClientToScreen(&pt); m_sampleListView.ClientToScreen(&listViewRect); ImageList_DragEnter(GetDesktopWindow(), pt.x, pt.y); draggingIcon = TRUE; SetCapture(); return 0; }
static HICON getOverlayedIcon(HICON icon, HICON overlay, BOOL big) { HIMAGELIST il = ImageList_Create( GetSystemMetrics(big?SM_CXICON:SM_CXSMICON), GetSystemMetrics(big?SM_CYICON:SM_CYSMICON), ILC_COLOR32|ILC_MASK, 2, 2); ImageList_AddIcon(il, icon); ImageList_AddIcon(il, overlay); HIMAGELIST newImage = ImageList_Merge(il,0,il,1,0,0); ImageList_Destroy(il); HICON hIcon = ImageList_GetIcon(newImage, 0, 0); ImageList_Destroy(newImage); return hIcon; // the result should be destroyed by DestroyIcon() }
int CIconList::CreateTabIconInt(LPCWSTR asIconDescr, bool bAdmin, LPCWSTR asWorkDir) { wchar_t* pszExpanded = ExpandEnvStr(asIconDescr); // Need to be created! int iIconIdx = -1; HICON hFileIcon = NULL; wchar_t szTemp[MAX_PATH]; LPCWSTR pszLoadFile = pszExpanded ? pszExpanded : asIconDescr; LPCWSTR lpszExt = (wchar_t*)PointToExt(pszLoadFile); bool bDirChanged = false; if (asWorkDir && *asWorkDir) { // Executable (or icon) file may be not availbale by %PATH%, let "cd" to it... bDirChanged = gpConEmu->ChangeWorkDir(asWorkDir); } if (!lpszExt) { LPWSTR pszFile = NULL; if (SearchPath(NULL, pszLoadFile, L".exe", countof(szTemp), szTemp, &pszFile)) { pszLoadFile = szTemp; lpszExt = (wchar_t*)PointToExt(pszLoadFile); } if (!lpszExt) goto wrap; } if (lstrcmpi(lpszExt, L".ico") == 0) { hFileIcon = (HICON)LoadImage(0, pszLoadFile, IMAGE_ICON, mn_CxIcon, mn_CyIcon, LR_DEFAULTCOLOR|LR_LOADFROMFILE); } else if ((lstrcmpi(lpszExt, L".exe") == 0) || (lstrcmpi(lpszExt, L".dll") == 0)) { //TODO: May be specified index of an icon in the file HICON hIconLarge = NULL, hIconSmall = NULL; ExtractIconEx(pszLoadFile, 0, &hIconLarge, &hIconSmall, 1); bool bUseLargeIcon = ((mn_CxIcon > 16) && (hIconLarge != NULL)) || (hIconSmall == NULL); HICON hDestroyIcon = bUseLargeIcon ? hIconSmall : hIconLarge; if (hDestroyIcon) DestroyIcon(hDestroyIcon); hFileIcon = bUseLargeIcon ? hIconLarge : hIconSmall; } else { //TODO: Shell icons for registered files (cmd, bat, sh, pl, py, ...) } if (hFileIcon) { wchar_t szIconInfo[80] = L"", szMergedInfo[80] = L""; GetIconInfoStr(hFileIcon, szIconInfo); if (gpSetCls->isAdvLogging) { CEStr lsLog(lstrmerge(L"Icon `", asIconDescr, L"` was loaded: ", szIconInfo)); gpConEmu->LogString(lsLog); } int iIconIdxAdm = -1; iIconIdx = ImageList_ReplaceIcon(mh_TabIcons, -1, hFileIcon); TabIconCache NewIcon = {lstrdup(asIconDescr), iIconIdx, false}; m_Icons.push_back(NewIcon); if (mn_AdminIcon >= 0) { HIMAGELIST hAdmList = ImageList_Merge(mh_TabIcons, iIconIdx, mh_TabIcons, mn_AdminIcon+2, 0,0); if (hAdmList) { HICON hNewIcon = ImageList_GetIcon(hAdmList, 0, ILD_TRANSPARENT); if (hNewIcon) { CEStr lsLog(lstrmerge(L"Admin icon `", asIconDescr, L"` was created: ", GetIconInfoStr(hNewIcon, szMergedInfo))); gpConEmu->LogString(lsLog); iIconIdxAdm = ImageList_ReplaceIcon(mh_TabIcons, -1, hNewIcon); DestroyIcon(hNewIcon); TabIconCache AdmIcon = {lstrdup(asIconDescr), iIconIdxAdm, true}; m_Icons.push_back(AdmIcon); if (bAdmin && (iIconIdxAdm > 0)) { iIconIdx = iIconIdxAdm; } } else { gpConEmu->LogString(L"GetIcon for admin icon was failed"); } ImageList_Destroy(hAdmList); } else { gpConEmu->LogString(L"Admin icon merging was failed"); } } DestroyIcon(hFileIcon); } wrap: if (bDirChanged) { gpConEmu->ChangeWorkDir(NULL); } SafeFree(pszExpanded); if (gpSetCls->isAdvLogging && (iIconIdx < 0)) { CEStr lsLog(lstrmerge(L"Icon `", asIconDescr, L"` loading was failed")); gpConEmu->LogString(lsLog); } return iIconIdx; }
int CIconList::CreateTabIcon(LPCWSTR asIconDescr, bool bAdmin) { if (!asIconDescr || !*asIconDescr) return GetTabIcon(bAdmin); for (INT_PTR i = 0; i < m_Icons.size(); i++) { const TabIconCache& icn = m_Icons[i]; if ((icn.bAdmin!=FALSE) != bAdmin) continue; if (lstrcmpi(icn.pszIconDescr, asIconDescr) != 0) continue; // Already was created! return icn.nIconIdx; } wchar_t* pszExpanded = ExpandEnvStr(asIconDescr); // Need to be created! int iIconIdx = -1; HICON hFileIcon = NULL; wchar_t szTemp[MAX_PATH]; LPCWSTR pszLoadFile = pszExpanded ? pszExpanded : asIconDescr; LPCWSTR lpszExt = (wchar_t*)PointToExt(pszLoadFile); if (!lpszExt) { LPWSTR pszFile = NULL; if (SearchPath(NULL, pszLoadFile, L".exe", countof(szTemp), szTemp, &pszFile)) { pszLoadFile = szTemp; lpszExt = (wchar_t*)PointToExt(pszLoadFile); } if (!lpszExt) goto wrap; } if (lstrcmpi(lpszExt, L".ico") == 0) { hFileIcon = (HICON)LoadImage(0, pszLoadFile, IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR|LR_LOADFROMFILE); } else if ((lstrcmpi(lpszExt, L".exe") == 0) || (lstrcmpi(lpszExt, L".dll") == 0)) { //TODO: May be specified index of an icon in the file HICON hIconLarge = NULL; ExtractIconEx(pszLoadFile, 0, &hIconLarge, &hFileIcon, 1); if (hIconLarge) DestroyIcon(hIconLarge); } else { //TODO: Shell icons for registered files (cmd, bat, sh, pl, py, ...) } if (hFileIcon) { int iIconIdxAdm = -1; iIconIdx = ImageList_ReplaceIcon(mh_TabIcons, -1, hFileIcon); TabIconCache NewIcon = {lstrdup(asIconDescr), false, iIconIdx}; m_Icons.push_back(NewIcon); HIMAGELIST hAdmList = ImageList_Merge(mh_TabIcons, iIconIdx, mh_TabIcons, mn_AdminIcon+2, 0,0); if (hAdmList) { HICON hNewIcon = ImageList_GetIcon(hAdmList, 0, ILD_TRANSPARENT); if (hNewIcon) { iIconIdxAdm = ImageList_ReplaceIcon(mh_TabIcons, -1, hNewIcon); DestroyIcon(hNewIcon); TabIconCache AdmIcon = {lstrdup(asIconDescr), true, iIconIdxAdm}; m_Icons.push_back(AdmIcon); if (bAdmin && (iIconIdxAdm > 0)) { iIconIdx = iIconIdxAdm; } } } //TODO: bAdmin!!! DestroyIcon(hFileIcon); } wrap: SafeFree(pszExpanded); return iIconIdx; }
BOOL CImageList::Create(CImageList& imagelist1, int nImage1, CImageList& imagelist2, int nImage2, int dx, int dy) { return Attach(ImageList_Merge(imagelist1.m_hImageList, nImage1, imagelist2.m_hImageList, nImage2, dx, dy)); }
/*-------------------------------*/ LRESULT CALLBACK WndProc(HWND hWnd, UINT komunikat, WPARAM wParam, LPARAM lParam) { static BOOL bDragging; static int poz; POINT pkt; HIMAGELIST hDragImgList; static NOTIFYICONDATA nim; switch (komunikat) { case WM_CREATE: HWND hToolTip; HFONT hFont; TOOLINFO tinf; RECT rect; /*-----tworzenie kontrolek-----*/ hList = CreateWindow("SysListView32", "lista_przyciskow", WS_VISIBLE | WS_CHILD | WS_BORDER | LVS_REPORT | LVS_SINGLESEL,0,0,493,230,hWnd,NULL,hInst, NULL); hRefresh = CreateWindow("button", "Odœwie¿ listê", WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, 135, 232, 100, 20, hWnd, NULL, hInst, NULL); hShow = CreateWindow("button", "Poka¿ przycisk", WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, 15, 232, 100, 20,/*255, 232, 100, 20,*/ hWnd, NULL, hInst, NULL); hInfo = CreateWindow("button", "O programie...", WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, 375, 232, 100, 20, hWnd, NULL, hInst, NULL); /*-----tworzenie i ustawianie czcionki dla przycisków-----*/ hFont = CreateFont(14, 0, 0, 0, 0, false, false, false, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, NULL); SendMessage(hRefresh, WM_SETFONT, (WPARAM) hFont, true); SendMessage(hShow, WM_SETFONT, (WPARAM) hFont, true); SendMessage(hInfo, WM_SETFONT, (WPARAM) hFont, true); ListView_SetExtendedListViewStyle(hList, LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_INFOTIP); /*-----ustawianie tooltipów-----*/ hToolTip = CreateWindow(TOOLTIPS_CLASS, NULL, TTS_ALWAYSTIP | TTS_BALLOON, 0,0,0,0, hWnd, NULL, hInst, NULL); //Ustawianie parametrów wspó³nych dla ka¿dego tooltipa: tytu³, kolor. SendMessage(hToolTip, TTM_SETTITLE, TTI_INFO, (LPARAM)"Skrót"); SendMessage(hToolTip, TTM_SETTIPTEXTCOLOR, (LPARAM)RGB(0, 0, 100), 0); SendMessage(hToolTip, TTM_SETTIPBKCOLOR, (LPARAM)RGB(250, 250, 250), 0); GetClientRect (hWnd, &rect); tinf.cbSize = sizeof(TOOLINFO); tinf.uFlags = TTF_SUBCLASS; tinf.hinst = hInst; tinf.uId = 0; tinf.rect.left = rect.left; tinf.rect.top = rect.top; tinf.rect.right = rect.right; tinf.rect.bottom = rect.bottom; tinf.hwnd = hRefresh; tinf.lpszText = "F5"; SendMessage(hToolTip, TTM_ADDTOOL, 0, (LPARAM)&tinf); tinf.hwnd = hShow; tinf.lpszText = "dwuklik LPM"; SendMessage(hToolTip, TTM_ADDTOOL, 0, (LPARAM)&tinf); tinf.hwnd = hInfo; tinf.lpszText = "F1"; SendMessage(hToolTip, TTM_ADDTOOL, 0, (LPARAM)&tinf); /*-----ustawianie ikony programu w zasobniku systemowym-----*/ nim.cbSize = sizeof(NOTIFYICONDATA); nim.hWnd = hWnd; nim.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP; nim.hIcon = ikona; nim.uCallbackMessage = WM_TRAY; nim.uID = 7; lstrcpyn(nim.szTip, "Manipulator by FeniX", sizeof(nim.szTip)); Shell_NotifyIcon(NIM_ADD, &nim); refresh(); break; case WM_KEYUP: //obs³uga skrótów klawiaturowych dla konkretnych akcji switch (wParam) { case VK_F5: SendMessage(hRefresh, BM_CLICK, 0, 0); break; case VK_F1: SendMessage(hInfo, BM_CLICK, 0, 0); break; case VK_SPACE: SendMessage(hShow, BM_CLICK, 0, 0); break; case VK_ESCAPE: ShowWindow(hWnd, SW_MINIMIZE); break; } break; case WM_COMMAND: //obs³uga zdarzeñ okien pochodnych okna g³ównego switch (HIWORD(wParam)) { case BN_CLICKED: //komunikat klikniêcia przycisku if ((HWND)lParam == hRefresh) { refresh(); SetFocus(hList); } else if ((HWND)lParam == hInfo) { MessageBox(hWnd, "Autor:\nKonrad Gadzina <*****@*****.**>\n" "Grupa 1131, Informatyka, rok akad. 2008/2009" "\nPracownia In¿ynierii Oprogramowania M-74\n" "Instytut Informatyki Stosowanej\n" "Wydzia³ Mechaniczny, Politechnika Krakowska\nJêzyki i Techniki Programowania", "O programie", MB_OK); } else if ((HWND)lParam == hShow) { int poz; char buf[10]; bool hidden; TBBUTTON *ptbb, tbb; NOTIFYICONDATA fake; //potrzebne do "odswiezania" paska zadan i dopasowywania szerokosci przyciskow ptbb = (TBBUTTON*)VirtualAllocEx(proces, NULL, sizeof(TBBUTTON), MEM_COMMIT, PAGE_READWRITE); poz = ListView_GetNextItem(hList, (WPARAM)-1, LVNI_SELECTED); SendMessage(hPasek, TB_GETBUTTON, (WPARAM)poz, (LPARAM)ptbb); ReadProcessMemory(proces, (void*)ptbb, (void*)&tbb, sizeof(TBBUTTON), NULL); hidden = SendMessage(hPasek, TB_ISBUTTONHIDDEN, (WPARAM)tbb.idCommand, 0); SendMessage(hPasek, TB_HIDEBUTTON, (WPARAM)tbb.idCommand, (LPARAM)!hidden); if (hidden) SendMessage(hShow, WM_SETTEXT, 0, (LPARAM)"Ukryj przycisk"); else SendMessage(hShow, WM_SETTEXT, 0, (LPARAM)"Poka¿ przycisk"); /*---dodawanie i usuwanie ikony do zasobnika, by pasek zadañ siê "odœwie¿y³"---*/ fake.cbSize = sizeof(NOTIFYICONDATA); fake.hWnd = hWnd; fake.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP; fake.hIcon = ikona; fake.uCallbackMessage = WM_TRAY; fake.uID = 19; lstrcpyn(fake.szTip, "Manipulator by FeniX", sizeof(fake.szTip)); Shell_NotifyIcon(NIM_ADD, &fake); Shell_NotifyIcon(NIM_DELETE, &fake); for (int i = 0; i<ile; i++) { SendMessage(hPasek, TB_GETBUTTON, (WPARAM)i, (LPARAM)ptbb); ReadProcessMemory(proces, (void*)ptbb, (void*)&tbb, sizeof(TBBUTTON), NULL); hidden = SendMessage(hPasek, TB_ISBUTTONHIDDEN, (WPARAM)tbb.idCommand, 0); if (!hidden) strcpy(buf, "[widoczny]"); else strcpy(buf, "[ukryty]"); ListView_SetItemText(hList, i, 1, buf); } SetFocus(hList); VirtualFreeEx(proces, ptbb, 0, MEM_RELEASE); } break; } break; case WM_TRAY: //obs³uga klikniêcia na ikonkê programu w zasobniku systemowym switch ((UINT)lParam) { case WM_LBUTTONDOWN: if (!IsWindowVisible(hWnd)) { if (IsZoomed(hWnd)) ShowWindow(hWnd, SW_MAXIMIZE); else ShowWindow(hWnd, SW_RESTORE); SetForegroundWindow(hWnd); } else if (GetForegroundWindow() == hWnd) ShowWindow(hWnd, SW_HIDE); else SetForegroundWindow(hWnd); break; } break; case WM_ACTIVATE: if (LOWORD(wParam) != WA_INACTIVE) refresh(); break; case WM_SIZE: //zdarzenie zmienienia rozmiaru int szer, wys; if (wParam & SIZE_MINIMIZED) ShowWindow(hWnd, SW_HIDE); szer = (int)LOWORD(lParam); wys = (int)HIWORD(lParam ); /* Poni¿ze linijki pozwalaj¹ przestawiaæ kontrolki tak, by dopasowa ich pozycjê/rozmiar do rozmiaru okna g³ównego */ MoveWindow(hList, 0, 0, szer, wys-23, false); MoveWindow(hShow, 20, wys-21, 120, 20, false); MoveWindow(hRefresh, szer-310, wys-21, 120, 20, false); MoveWindow(hInfo, szer-140, wys-21, 120, 20, false); break; case WM_SIZING: //zdarzenie zmieniania rozmiaru RECT* rc; rc = (RECT*)lParam; /* Poni¿sze linie pozwalaj¹ ograniczyc rozmiar okna - jako, ¿e to zdarzenie jest wywo³ywane w trakcie zmiany rozmiaru, warunki s¹ sprawdzane nie po puszczeniu przycisku myszy, a jeszcze w trakcie jego trzymania. Dziêki temu okno nie nigdy nie bêdzie mia³o rozmiarów mniejszych ni¿ 500x100 pikseli. */ if (rc->right - rc->left <= 500) rc->right = rc->left + 500; if (rc->bottom - rc->top <= 100) rc->bottom = rc->top + 100; break; case WM_DESTROY: //zdarzenie niszczenia okna CloseHandle(proces); Shell_NotifyIcon(NIM_DELETE, &nim); PostQuitMessage(0); break; case WM_NOTIFY: //obs³uga komunikatów od kontrolki ListView if (((LPNMHDR)lParam)->hwndFrom == hList && ((LPNMHDR)lParam)->code == (unsigned int)NM_DBLCLK) SendMessage(hShow, BM_CLICK, 0, 0); else if (((LPNMHDR)lParam)->hwndFrom == hList && ((LPNMHDR)lParam)->code == (unsigned int)NM_CLICK) { char buf[10]; int poz = ListView_GetNextItem(hList, (WPARAM)-1, LVNI_SELECTED); ListView_GetItemText(hList, poz, 1, buf, 50); if (!strcmp(buf, "[ukryty]")) SendMessage(hShow, WM_SETTEXT, 0, (LPARAM)"Poka¿ przycisk"); else SendMessage(hShow, WM_SETTEXT, 0, (LPARAM)"Ukryj przycisk"); } else if (((LPNMHDR)lParam)->hwndFrom == hList && ((LPNMHDR)lParam)->code == LVN_KEYDOWN) { switch (((LV_KEYDOWN*)lParam)->wVKey) { case VK_F5: SendMessage(hRefresh, BM_CLICK, 0, 0); break; case VK_F1: SendMessage(hInfo, BM_CLICK, 0, 0); break; case VK_SPACE: SendMessage(hShow, BM_CLICK, 0, 0); break; case VK_ESCAPE: ShowWindow(hWnd, SW_MINIMIZE); break; } } /*------------------- obs³uga drag & drop na liœcie z przyciskami -------------------*/ else if (((LPNMHDR)lParam)->hwndFrom == hList && ((LPNMHDR)lParam)->code == LVN_BEGINDRAG) { //wiadomoœæ wysy³ana do okna g³ównego, gdy rozpoczynamy drag & drop na liœcie //czyli ³apiemy element lewym przyciskiem myszy HIMAGELIST hOneImageList, hTempImageList; IMAGEINFO imginf; int x = 0, wys; pkt.x = 1; pkt.y = 1; poz = ListView_GetNextItem(hList, (WPARAM)-1, LVNI_SELECTED); //pobieranie indexu zaznaczonego elementu item.iItem = poz; item.mask = LVIF_IMAGE | LVIF_INDENT | LVIF_PARAM; //ustawienie maski elementu listy do pobrania ListView_GetItem(hList, &item); //pobieranie danego elementu do zmiennej item if (item.iIndent) //element z wciêciem nas nie interesuje break; hDragImgList = ListView_CreateDragImage(hList, poz, &pkt); //tworzenie "duszka" do d&d ImageList_GetImageInfo(hDragImgList, 0, &imginf); wys = imginf.rcImage.bottom; while(true) //dodawanie elementów danej grupy do "duszka" w pêtli { if (++item.iItem >= ile) break; item.mask = LVIF_IMAGE | LVIF_INDENT | LVIF_PARAM; //ustawianie maski pobierania danych elementu ListView_GetItem(hList, &item); if(item.iIndent == 0) //je¿eli napotkano kolejny przycisk grupowy trzeba przerwaæ break; hOneImageList = ListView_CreateDragImage(hList, item.iItem, &pkt); hTempImageList = ImageList_Merge(hDragImgList, 0, hOneImageList, 0, 0, wys); ImageList_Destroy(hDragImgList); ImageList_Destroy(hOneImageList); hDragImgList = hTempImageList; ImageList_GetImageInfo(hDragImgList, 0, &imginf); wys = imginf.rcImage.bottom; } item.iItem = poz; item.mask = LVIF_IMAGE | LVIF_INDENT | LVIF_PARAM; ListView_GetItem(hList, &item); ImageList_BeginDrag(hDragImgList, 0, x, 0); pkt = ((NM_LISTVIEW*) ((LPNMHDR)lParam))->ptAction; ClientToScreen(hList, &pkt); ImageList_DragEnter(GetDesktopWindow(), pkt.x, pkt.y); bDragging = true; SetCapture(hWnd); } break; case WM_MOUSEMOVE: //zdarzenie ruchu kursora myszy if (!bDragging) //je¿eli nie obs³gujemy akurat d&d na liœcie to nie trzeba nic robiæ break; pkt.x = LOWORD(lParam); pkt.y = HIWORD(lParam); ClientToScreen(hWnd, &pkt); ImageList_DragMove(pkt.x, pkt.y); break; case WM_LBUTTONUP: //zdarzenie puszczenia lewego przycisku myszy if (!bDragging) //je¿eli nie obs³gujemy akurat d&d na liœcie to nie trzeba nic robiæ break; LVHITTESTINFO lvhti; char buf[256], sub[12]; /*---puszczamy przycisk, wiêc przeci¹ganie siê koñczy---*/ bDragging = false; ImageList_DragLeave(hList); ImageList_EndDrag(); //ImageList_Destroy(hDragImgList); //nie wiem czemu, ale ta linia wywo³uje b³¹d segfault przy uruchomieniu debuggera ReleaseCapture(); /*---sprawdzanie, czy przeci¹gany element zosta³ upuszczony na inny element listy---*/ lvhti.pt.x = LOWORD(lParam); lvhti.pt.y = HIWORD(lParam); ClientToScreen(hWnd, &lvhti.pt); ScreenToClient(hList, &lvhti.pt); ListView_HitTest(hList, &lvhti); if (lvhti.iItem == -1) break; if ((lvhti.flags & LVHT_ONITEMLABEL == 0) && (lvhti.flags & LVHT_ONITEMSTATEICON == 0)) break; if (!item.iIndent) //je¿eli wciêcie = 0, to znaczy ¿e zajmujemy siê przyciskiem "grupowym" { poz = ListView_GetNextItem(hList, (WPARAM)-1, LVNI_SELECTED); if (lvhti.iItem > poz) lvhti.iItem++; while (true) { if (lvhti.iItem == poz || lvhti.iItem > ile-1 || lvhti.iItem < 0) break; item.iItem = lvhti.iItem; item.iSubItem = 0; item.mask = LVIF_STATE | LVIF_IMAGE | LVIF_INDENT | LVIF_TEXT | LVIF_PARAM; item.stateMask = LVIS_SELECTED; ListView_GetItem(hList, &item); if (item.iIndent) { if (lvhti.iItem > poz) lvhti.iItem++; else if (lvhti.iItem < poz) lvhti.iItem--; } else { if (lvhti.iItem > poz) lvhti.iItem--; break; } } ListView_GetItemText(hList, poz, 0, buf, 256); //pobieranie tekstu danego elementu listy while (true) { int tmp = poz; item.iItem = poz; item.iSubItem = 0; item.cchTextMax = 256; item.pszText = buf; item.stateMask = ~LVIS_SELECTED; item.mask = LVIF_STATE | LVIF_IMAGE | LVIF_INDENT | LVIF_TEXT | LVIF_PARAM; ListView_GetItem(hList, &item); ListView_GetItemText(hList, poz, 1, sub, 12); SendMessage(hPasek, TB_MOVEBUTTON, (WPARAM)poz, (LPARAM)lvhti.iItem); if (lvhti.iItem > poz && lvhti.iItem < ile) lvhti.iItem++; item.iItem = lvhti.iItem; ListView_InsertItem(hList, &item); ListView_SetItemText(hList, item.iItem, 1, sub); if (lvhti.iItem < poz) poz++; ListView_DeleteItem(hList, poz); if (lvhti.iItem > tmp) lvhti.iItem--; if (lvhti.iItem < tmp) lvhti.iItem++; ListView_GetItemText(hList, poz, 0, buf, 256); item.iItem = poz; item.iSubItem = 0; item.cchTextMax = 256; item.pszText = buf; ListView_GetItem(hList, &item); if (!item.iIndent || poz > ile-1) //je¿eli break; } } break; default: return DefWindowProc(hWnd, komunikat, wParam, lParam); } return 0; }
int CIconList::CreateTabIconInt(LPCWSTR asIconDescr, bool bAdmin, LPCWSTR asWorkDir) { wchar_t* pszExpanded = ExpandEnvStr(asIconDescr); // Need to be created! int iIconIdx = -1; HICON hFileIcon = NULL; wchar_t szTemp[MAX_PATH]; LPCWSTR pszLoadFile = pszExpanded ? pszExpanded : asIconDescr; LPCWSTR lpszExt = (wchar_t*)PointToExt(pszLoadFile); bool bDirChanged = false; if (asWorkDir && *asWorkDir) { // Executable (or icon) file may be not availbale by %PATH%, let "cd" to it... bDirChanged = gpConEmu->ChangeWorkDir(asWorkDir); } if (!lpszExt) { LPWSTR pszFile = NULL; if (SearchPath(NULL, pszLoadFile, L".exe", countof(szTemp), szTemp, &pszFile)) { pszLoadFile = szTemp; lpszExt = (wchar_t*)PointToExt(pszLoadFile); } if (!lpszExt) goto wrap; } if (lstrcmpi(lpszExt, L".ico") == 0) { hFileIcon = (HICON)LoadImage(0, pszLoadFile, IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR|LR_LOADFROMFILE); } else if ((lstrcmpi(lpszExt, L".exe") == 0) || (lstrcmpi(lpszExt, L".dll") == 0)) { //TODO: May be specified index of an icon in the file HICON hIconLarge = NULL; ExtractIconEx(pszLoadFile, 0, &hIconLarge, &hFileIcon, 1); if (hIconLarge) DestroyIcon(hIconLarge); } else { //TODO: Shell icons for registered files (cmd, bat, sh, pl, py, ...) } if (hFileIcon) { int iIconIdxAdm = -1; iIconIdx = ImageList_ReplaceIcon(mh_TabIcons, -1, hFileIcon); TabIconCache NewIcon = {lstrdup(asIconDescr), false, iIconIdx}; m_Icons.push_back(NewIcon); HIMAGELIST hAdmList = ImageList_Merge(mh_TabIcons, iIconIdx, mh_TabIcons, mn_AdminIcon+2, 0,0); if (hAdmList) { HICON hNewIcon = ImageList_GetIcon(hAdmList, 0, ILD_TRANSPARENT); if (hNewIcon) { iIconIdxAdm = ImageList_ReplaceIcon(mh_TabIcons, -1, hNewIcon); DestroyIcon(hNewIcon); TabIconCache AdmIcon = {lstrdup(asIconDescr), true, iIconIdxAdm}; m_Icons.push_back(AdmIcon); if (bAdmin && (iIconIdxAdm > 0)) { iIconIdx = iIconIdxAdm; } } } //TODO: bAdmin!!! DestroyIcon(hFileIcon); } wrap: if (bDirChanged) { gpConEmu->ChangeWorkDir(NULL); } SafeFree(pszExpanded); return iIconIdx; }
static LRESULT CALLBACK GROUP_GroupWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { PROGGROUP* group; INT iItem; LVITEMW lvItem; POINT pt; group = (PROGGROUP*)GetWindowLongPtrW(hWnd, 0); switch (uMsg) { case WM_NCCREATE: { LPCREATESTRUCTW pcs = (LPCREATESTRUCTW)lParam; LPMDICREATESTRUCTW pMDIcs = (LPMDICREATESTRUCTW)pcs->lpCreateParams; group = (PROGGROUP*)pMDIcs->lParam; SetWindowLongPtrW(hWnd, 0, (LONG_PTR)group); if (group->bIsCommonGroup) { DefMDIChildProcW(hWnd, WM_SETICON, ICON_BIG, (LPARAM)CopyImage(Globals.hCommonGroupIcon, IMAGE_ICON, GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON), LR_COPYFROMRESOURCE)); DefMDIChildProcW(hWnd, WM_SETICON, ICON_SMALL, (LPARAM)CopyImage(Globals.hCommonGroupIcon, IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_COPYFROMRESOURCE)); } else { DefMDIChildProcW(hWnd, WM_SETICON, ICON_BIG, (LPARAM)CopyImage(Globals.hPersonalGroupIcon, IMAGE_ICON, GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON), LR_COPYFROMRESOURCE)); DefMDIChildProcW(hWnd, WM_SETICON, ICON_SMALL, (LPARAM)CopyImage(Globals.hPersonalGroupIcon, IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_COPYFROMRESOURCE)); } break; } case WM_NCDESTROY: SetWindowLongPtrW(hWnd, 0, 0); break; case WM_CREATE: { DWORD dwStyle; RECT rect; GetClientRect(hWnd, &rect); group->hListView = CreateWindowW(WC_LISTVIEW, NULL, WS_CHILD | WS_VISIBLE | WS_OVERLAPPED, 0, 0, rect.right - rect.left, rect.bottom - rect.top, hWnd, NULL, Globals.hInstance, NULL); dwStyle = (GetWindowLongPtrW(group->hListView, GWL_STYLE) | LVS_SHOWSELALWAYS) & ~LVS_AUTOARRANGE; SetWindowLongPtrW(group->hListView, GWL_STYLE, dwStyle); dwStyle = SendMessageA(group->hListView, LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0) | LVS_EX_BORDERSELECT; SendMessageA(group->hListView, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_SNAPTOGRID, dwStyle); InitUxTheme(); SetWindowTheme(group->hListView, L"Explorer", NULL); group->hListLarge = ImageList_Create(GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON), ILC_COLOR24 | ILC_MASK, 1, 1); SendMessageA(group->hListView, LVM_SETIMAGELIST, 0, (LPARAM)group->hListLarge); SendMessageA(group->hListView, LVM_SETICONSPACING, 0, MAKELPARAM(80, 64)); break; } case WM_DESTROY: { SendMessageA(group->hListView, LVM_SETIMAGELIST, 0, 0); ImageList_Destroy(group->hListLarge); DestroyWindow(group->hListView); break; } case WM_SIZE: { RECT rect; rect.left = 0; rect.top = 0; rect.right = LOWORD(lParam); rect.bottom = HIWORD(lParam); AdjustWindowRectEx(&rect, GetWindowLongPtrW(group->hListView, GWL_STYLE), FALSE, GetWindowLongPtrW(group->hListView, GWL_EXSTYLE)); MoveWindow(group->hListView, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, TRUE); break; } case WM_CLOSE: SendMessageW(hWnd, WM_SYSCOMMAND, SC_MINIMIZE, 0); break; case WM_SYSCOMMAND: if (wParam == SC_CLOSE) wParam = SC_MINIMIZE; break; case WM_CHILDACTIVATE: case WM_NCLBUTTONDOWN: Globals.hActiveGroup = (PROGGROUP*)GetWindowLongPtrW(hWnd, 0); Globals.hActiveGroup->hActiveProgram = NULL; break; case WM_NOTIFY: switch (((LPNMHDR)lParam)->code) { case NM_CLICK: { iItem = ((LPNMITEMACTIVATE)lParam)->iItem; if (iItem == -1) { group->hActiveProgram = NULL; break; } lvItem.mask = LVIF_PARAM; lvItem.iItem = iItem; SendMessageW(group->hListView, LVM_GETITEMW, 0, (LPARAM)&lvItem); group->hActiveProgram = (PROGRAM*)lvItem.lParam; break; } case NM_DBLCLK: { iItem = ((LPNMITEMACTIVATE)lParam)->iItem; if (iItem == -1) break; lvItem.mask = LVIF_PARAM; lvItem.iItem = iItem; SendMessageW(group->hListView, LVM_GETITEMW, 0, (LPARAM)&lvItem); /* ... or use group->hActiveProgram */ PROGRAM_ExecuteProgram((PROGRAM*)lvItem.lParam); break; } case LVN_BEGINDRAG: { POINT ptMin; BOOL bFirst = TRUE; for (iItem = SendMessageA(group->hListView, LVM_GETNEXTITEM, -1, LVNI_SELECTED); iItem != -1; iItem = SendMessageA(group->hListView, LVM_GETNEXTITEM, iItem, LVNI_SELECTED)) { if (bFirst) { group->hDragImageList = (HIMAGELIST)SendMessageA(group->hListView, LVM_CREATEDRAGIMAGE, iItem, (LPARAM)&pt); ptMin = pt; bFirst = FALSE; } else { HIMAGELIST hOneImageList, hTempImageList; hOneImageList = (HIMAGELIST)SendMessageA(group->hListView, LVM_CREATEDRAGIMAGE, iItem, (LPARAM)&pt); hTempImageList = ImageList_Merge(group->hDragImageList, 0, hOneImageList, 0, pt.x - ptMin.x, pt.y - ptMin.y); ImageList_Destroy(group->hDragImageList); ImageList_Destroy(hOneImageList); group->hDragImageList = hTempImageList; ptMin.x = min(ptMin.x, pt.x); ptMin.y = min(ptMin.y, pt.y); } } // pt = ((LPNMLISTVIEW)lParam)->ptAction; pt.x = ((LPNMLISTVIEW)lParam)->ptAction.x; pt.y = ((LPNMLISTVIEW)lParam)->ptAction.y; group->ptStart = pt; pt.x -= ptMin.x; pt.y -= ptMin.y; ImageList_BeginDrag(group->hDragImageList, 0, pt.x, pt.y); MapWindowPoints(group->hListView, Globals.hMDIWnd, &pt, 1); ImageList_DragEnter(Globals.hMDIWnd, pt.x, pt.y); group->bDragging = TRUE; group->hOldCursor = GetCursor(); SetCapture(group->hWnd); break; } } break; case WM_MOUSEMOVE: if (group->bDragging) { pt.x = GET_X_LPARAM(lParam); pt.y = GET_Y_LPARAM(lParam); MapWindowPoints(group->hWnd, Globals.hMDIWnd, &pt, 1); ImageList_DragMove(pt.x, pt.y); } break; case WM_LBUTTONUP: if (group->bDragging) { // LVHITTESTINFO lvhti; POINT ptHit; group->bDragging = FALSE; ImageList_DragLeave(Globals.hMDIWnd); ImageList_EndDrag(); ImageList_Destroy(group->hDragImageList); ReleaseCapture(); SetCursor(group->hOldCursor); ptHit.x = GET_X_LPARAM(lParam); ptHit.y = GET_Y_LPARAM(lParam); MapWindowPoints(group->hWnd, group->hListView, &ptHit, 1); for (iItem = SendMessageA(group->hListView, LVM_GETNEXTITEM, -1, LVNI_SELECTED); iItem != -1; iItem = SendMessageA(group->hListView, LVM_GETNEXTITEM, iItem, LVNI_SELECTED)) { SendMessageA(group->hListView, LVM_GETITEMPOSITION, iItem, (LPARAM)&pt); pt.x += ptHit.x - group->ptStart.x; pt.y += ptHit.y - group->ptStart.y; SendMessageA(group->hListView, LVM_SETITEMPOSITION, iItem, MAKELPARAM(pt.x, pt.y)); } } break; } return DefMDIChildProcW(hWnd, uMsg, wParam, lParam); }
void SmartListCtrl::OnBeginDrag(NMHDR* pNMHDR, LRESULT* pResult) { *pResult = 0; if ( !eventHandler_ ) return; LPNMLISTVIEW info = (LPNMLISTVIEW)pNMHDR; std::string text; int image; getData( info->iItem, text, image ); POINT pt; GetCursorPos( &pt ); if ( dragImgList_ ) { delete dragImgList_; dragImgList_ = 0; } int pos = GetNextItem( -1, LVNI_SELECTED ); bool isFirst = true; int xoff = 0; int yoff = 0; int xstep = 0; int ystep = 0; IMAGEINFO imf; int maxDragWidth = 400; int maxDragHeight = 350; while ( pos != -1 ) { if ( isFirst ) { dragImgList_ = CreateDragImage( pos, &pt ); dragImgList_->GetImageInfo( 0, &imf ); xstep = imf.rcImage.right - imf.rcImage.left; ystep = imf.rcImage.bottom - imf.rcImage.top; yoff = imf.rcImage.bottom; isFirst = false; } else { if ( yoff + ystep > maxDragHeight && xoff + xstep > maxDragWidth ) generateDragListEndItem_ = true; // reached the max, so generate a 'more...' item in GetData CImageList* oneImgList = CreateDragImage( pos, &pt ); generateDragListEndItem_ = false; CImageList* tempImgList = new CImageList(); tempImgList->Attach( ImageList_Merge( dragImgList_->GetSafeHandle(), 0, oneImgList->GetSafeHandle(), 0, xoff, yoff ) ); delete dragImgList_; delete oneImgList; dragImgList_ = tempImgList; dragImgList_->GetImageInfo( 0, &imf ); yoff += ystep; if ( yoff > maxDragHeight ) { xoff += xstep; if ( xoff > maxDragWidth ) break; yoff = 0; } } pos = GetNextItem( pos, LVNI_SELECTED ); } if ( dragImgList_ ) { CPoint offset( thumbWidthCur_ + 16 , max( 16, thumbHeightCur_ - 14 ) ); dragImgList_->SetBkColor( GetBkColor() ); dragImgList_->SetDragCursorImage( 0, offset ); dragImgList_->BeginDrag( 0, offset ); dragImgList_->DragEnter( 0, pt ); } if ( delayedSelectionPending_ ) { // if a selection timer is pending, force it delayedSelectionNotify(); } dragging_ = true; eventHandler_->listStartDrag( info->iItem ); }