예제 #1
0
size_t VMenu2::SetUserData(LPCVOID Data, size_t Size, intptr_t Position)
{
	if(Position<0)
		Position=GetSelectPos();

	FarListItemData flid={sizeof(FarListItemData), Position, Size, const_cast<void*>(Data)};
	return SendMessage(DM_LISTSETDATA, 0, &flid);
}
예제 #2
0
LISTITEMFLAGS VMenu2::GetItemFlags(int Position)
{
	if(Position<0)
		Position=GetSelectPos();

	FarListGetItem flgi={sizeof(FarListGetItem), Position};
	SendMessage(DM_LISTGETITEM, 0, &flgi);
	return flgi.Item.Flags;
}
예제 #3
0
void VMenu2::UpdateItemFlags(int Pos, UINT64 NewFlags)
{
	if(Pos<0)
		Pos=GetSelectPos();
	FarListGetItem flgi={sizeof(FarListGetItem), Pos};
	SendMessage(DM_LISTGETITEM, 0, &flgi);
	flgi.Item.Flags=NewFlags;

	FarListUpdate flu={sizeof(FarListUpdate), Pos, flgi.Item};
	SendMessage(DM_LISTUPDATE, 0, &flu);
}
예제 #4
0
void *VMenu2::GetUserData(void *Data, size_t Size, intptr_t Position)
{
	if(Position<0)
		Position=GetSelectPos();
	void *d=(void*)SendMessage(DM_LISTGETDATA, 0, (void*)Position);
	size_t s=SendMessage(DM_LISTGETDATASIZE, 0, (void*)Position);

	if (d && Size && Data && Size>=s)
		memcpy(Data, d, s);

	return d;
}
예제 #5
0
intptr_t VMenu2::GetExitCode()
{
	if(cancel || Dialog::GetExitCode()<0)
		return -1;
	return GetSelectPos();
}
예제 #6
0
intptr_t VMenu2::VMenu2DlgProc(Dialog* Dlg, intptr_t Msg, intptr_t Param1, void* Param2)
{
	_DIALOG(CleverSysLog CL(L"VMenu2::VMenu2DlgProc()"));
	_DIALOG(SysLog(L"hDlg=%p, Msg=%s, Param1=%d (0x%08X), Param2=%d (0x%08X)",Dlg,_DLGMSG_ToName(Msg),Param1,Param1,Param2,Param2));
	switch(Msg)
	{
	case DN_CTLCOLORDIALOG:
		{
			FarColor *color=(FarColor*)Param2;
			*color=colors::PaletteColorToFarColor(COL_MENUBOX);
			return true;
		}

	case DN_CTLCOLORDLGLIST:
		{
			FarDialogItemColors *colors=(FarDialogItemColors*)Param2;

			PaletteColors MenuColors[]=
			{
				COL_MENUBOX,                               // подложка
				COL_MENUBOX,                               // рамка
				COL_MENUTITLE,                             // заголовок - верхний и нижний
				COL_MENUTEXT,                              // Текст пункта
				COL_MENUHIGHLIGHT,                         // HotKey
				COL_MENUBOX,                               // separator
				COL_MENUSELECTEDTEXT,                      // Выбранный
				COL_MENUSELECTEDHIGHLIGHT,                 // Выбранный - HotKey
				COL_MENUSCROLLBAR,                         // ScrollBar
				COL_MENUDISABLEDTEXT,                      // Disabled
				COL_MENUARROWS,                            // Arrow
				COL_MENUARROWSSELECTED,                    // Выбранный - Arrow
				COL_MENUARROWSDISABLED,                    // Arrow Disabled
				COL_MENUGRAYTEXT,                          // "серый"
				COL_MENUSELECTEDGRAYTEXT,                  // выбранный "серый"
			};
			for(size_t i=0; i<colors->ColorsCount && i<ARRAYSIZE(MenuColors); ++i)
				colors->Colors[i]=colors::PaletteColorToFarColor(MenuColors[i]);

			return true;
		}

	case DN_CLOSE:
		if(!ForceClosing && !Param1 && GetItemFlags() & (LIF_GRAYED|LIF_DISABLE))
			return false;
		if(Call(Msg, (void*)(Param1<0 ? Param1 : GetSelectPos())))
			return false;
		break;

	case DN_LISTHOTKEY:
		if (!Call(Msg, Param2))
			Dlg->SendMessage( DM_CLOSE, -1, nullptr);
		break;

	case DN_DRAWDLGITEMDONE: //???
	case DN_DRAWDIALOGDONE:
		if(DefRec.EventType)
		{
			INPUT_RECORD rec=DefRec;
			ClearStruct(DefRec);
			if(!Call(DN_INPUT, &rec))
				Dlg->SendMessage( DM_KEY, 1, &rec);
		}
		break;

	case DN_CONTROLINPUT:
	case DN_INPUT:
		if(!cancel)
		{
			if (Msg==DN_CONTROLINPUT)
			{
				auto ir = static_cast<INPUT_RECORD*>(Param2);
				int key=InputRecordToKey(ir);

				if(ListBox().ProcessFilterKey(key))
					return true;
			}

			if(Call(DN_INPUT, Param2))
				return Msg==DN_CONTROLINPUT;
		}
		break;

	case DN_LISTCHANGE:
	case DN_ENTERIDLE:
		if(!cancel)
		{
			if(Call(Msg, Param2))
				return false;
		}
		break;

	case DN_RESIZECONSOLE:
		if(!cancel)
		{
			INPUT_RECORD ReadRec={WINDOW_BUFFER_SIZE_EVENT};
			ReadRec.Event.WindowBufferSizeEvent.dwSize=*(COORD*)Param2;
			if(Call(DN_INPUT, &ReadRec))
				return false;
			else
				Resize();
		}
		break;

	default:
		if(Global->CloseFARMenu)
			ProcessKey(Manager::Key(KEY_ESC));
		break;
	}
	return Dlg->DefProc(Msg, Param1, Param2);
}
예제 #7
0
void ShowProcessList()
{
	static bool Active = false;
	if (Active)
		return;
	Active = true;
	SCOPE_EXIT{ Active = false; };

	const auto ProcList = VMenu2::create(msg(lng::MProcessListTitle), {}, ScrY - 4);
	ProcList->SetMenuFlags(VMENU_WRAPMODE);
	ProcList->SetPosition({ -1, -1, 0, 0 });
	bool ShowImage = false;

	const auto FillProcList = [&]
	{
		ProcList->clear();

		ProcInfo Info{ ProcList.get(), ShowImage };
		if (!EnumWindows(EnumWindowsProc, reinterpret_cast<LPARAM>(&Info)))
		{
			rethrow_if(Info.ExceptionPtr);
			return false;
		}

		ProcList->SortItems([](const MenuItemEx& a, const MenuItemEx& b, SortItemParam&)
		{
			return string_sort::less(std::any_cast<const menu_data&>(a.ComplexUserData).Title, std::any_cast<const menu_data&>(b.ComplexUserData).Title);
		});

		return true;
	};

	if (!FillProcList())
		return;

	ProcList->AssignHighlights(FALSE);
	ProcList->SetBottomTitle(msg(lng::MProcessListBottom));

	ProcList->Run([&](const Manager::Key& RawKey)
	{
		const auto Key=RawKey();
		int KeyProcessed = 1;
		switch (Key)
		{
			case KEY_F1:
				help::show(L"TaskList"sv);
				break;

			case KEY_NUMDEL:
			case KEY_DEL:
			{
				if (const auto MenuData = ProcList->GetComplexUserDataPtr<menu_data>())
				{
					if (Message(MSG_WARNING,
						msg(lng::MKillProcessTitle),
						{
							msg(lng::MAskKillProcess),
							MenuData->Title,
							msg(lng::MKillProcessWarning)
						},
						{ lng::MKillProcessKill, lng::MCancel }) == Message::first_button)
					{
						const os::handle Process(OpenProcess(PROCESS_TERMINATE, FALSE, MenuData->Pid));
						if (!Process || !TerminateProcess(Process.native_handle(), 0xFFFFFFFF))
						{
							const auto ErrorState = error_state::fetch();

							Message(MSG_WARNING, ErrorState,
								msg(lng::MKillProcessTitle),
								{
									msg(lng::MCannotKillProcess)
								},
								{ lng::MOk });
						}
					}
				}
			}
			[[fallthrough]];
			case KEY_CTRLR:
			case KEY_RCTRLR:
			{
				if (!FillProcList())
					ProcList->Close(-1);
				break;
			}

			case KEY_F2:
			{
				// TODO: change titles, don't enumerate again
				ShowImage = !ShowImage;
				const auto SelectPos = ProcList->GetSelectPos();
				if (!FillProcList())
				{
					ProcList->Close(-1);
				}
				else
				{
					ProcList->SetSelectPos(SelectPos);
				}
				break;
			}


			default:
				KeyProcessed = 0;
		}
		return KeyProcessed;
	});

	if (ProcList->GetExitCode() < 0)
		return;

	const auto MenuData = ProcList->GetComplexUserDataPtr<menu_data>();
	if (!MenuData)
		return;

	SwitchToWindow(MenuData->Hwnd);
}
예제 #8
0
void ShowProcessList()
{
	static bool Active = false;
	if (Active)
		return;
	Active = true;

	auto ProcList = VMenu2::create(MSG(MProcessListTitle), nullptr, 0, ScrY - 4);
	ProcList->SetMenuFlags(VMENU_WRAPMODE);
	ProcList->SetPosition(-1,-1,0,0);
	static bool bShowImage = false;

	ProcInfo pi = {ProcList.get(), bShowImage};

	if (EnumWindows(EnumWindowsProc,(LPARAM)&pi))
	{
		ProcList->AssignHighlights(FALSE);
		ProcList->SetBottomTitle(MSG(MProcessListBottom));
		ProcList->SortItems(TaskSort);

		ProcList->Run([&](const Manager::Key& RawKey)->int
		{
			const auto Key=RawKey.FarKey();
			int KeyProcessed = 1;
			switch (Key)
			{
				case KEY_F1:
				{
					Help::create(L"TaskList");
					break;
				}

				case KEY_NUMDEL:
				case KEY_DEL:
				{
					auto ProcWnd = *static_cast<HWND*>(ProcList->GetUserData(nullptr, 0));

					if (ProcWnd)
					{
						wchar_t_ptr Title;
						int LenTitle=GetWindowTextLength(ProcWnd);

						if (LenTitle)
						{
							Title.reset(LenTitle + 1);

							if (Title && (LenTitle=GetWindowText(ProcWnd, Title.get(), LenTitle+1)))
								Title[LenTitle]=0;
						}

						DWORD ProcID;
						GetWindowThreadProcessId(ProcWnd,&ProcID);

						if (!Message(MSG_WARNING,2,MSG(MKillProcessTitle),MSG(MAskKillProcess),
									NullToEmpty(Title.get()),MSG(MKillProcessWarning),MSG(MKillProcessKill),MSG(MCancel)))
						{
							if (KillProcess(ProcID))
								Sleep(500);
							else
							{
								Global->CatchError();
								Message(MSG_WARNING|MSG_ERRORTYPE,1,MSG(MKillProcessTitle),MSG(MCannotKillProcess),MSG(MOk));
							}
						}
					}
				}
				case KEY_CTRLR:
				case KEY_RCTRLR:
				{
					ProcList->DeleteItems();

					if (!EnumWindows(EnumWindowsProc,(LPARAM)&pi))
						ProcList->Close(-1);
					else
						ProcList->SortItems(TaskSort);
					break;
				}
				case KEY_F2:
				{
					pi.bShowImage=(bShowImage=!bShowImage);
					int SelectPos=ProcList->GetSelectPos();
					ProcList->DeleteItems();

					if (!EnumWindows(EnumWindowsProc,(LPARAM)&pi))
						ProcList->Close(-1);
					else
					{
						ProcList->SortItems(TaskSort);
						ProcList->SetSelectPos(SelectPos);
					}
					break;
				}


				default:
					KeyProcessed = 0;
			}
			return KeyProcessed;
		});

		if (ProcList->GetExitCode()>=0)
		{
			auto ProcWnd = *static_cast<HWND*>(ProcList->GetUserData(nullptr, 0));

			if (ProcWnd)
			{
				//SetForegroundWindow(ProcWnd);
				// Allow SetForegroundWindow on Win98+.
				DWORD dwMs;
				// Remember the current value.
				BOOL bSPI = SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, &dwMs, 0);

				if (bSPI) // Reset foreground lock timeout
					bSPI = SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, 0, 0);

				SetForegroundWindow(ProcWnd);

				if (bSPI) // Restore old value
					SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, ToPtr(dwMs), 0);

				WINDOWPLACEMENT wp = { sizeof(wp) };
				if (!GetWindowPlacement(ProcWnd,&wp) || wp.showCmd!=SW_SHOWMAXIMIZED)
					ShowWindowAsync(ProcWnd,SW_RESTORE);
			}
		}
	}
	Active = false;
}