class MainForm : Form
{
public MainForm()
{
InitializeComponent();
// 必要なコントロール
// ・リストビュー: lsWndInfo
// ・カラムヘッダー ×2(リストビュー用)
// あると便利なコントロール
// ・チェックボックス: checkTopMost
lsWndInfo.ShowGroups = true;
lsWndInfo.View = View.Details;
lsWndInfo.MouseDoubleClick += LsWndInfo_MouseDoubleClick;
checkTopMost.Text = "最前面";
checkTopMost.CheckedChanged += checkTopMost_CheckedChanged;
var vg = new ListViewGroup("Explorer");
vg.Name = "Explorer";
lsWndInfo.Groups.Add(vg);
CallEnumWindow();
}
private void LsWndInfo_MouseDoubleClick(object sender, MouseEventArgs e)
{
var vi = lsWndInfo.GetItemAt(e.X, e.Y);
var wi = (CWndInfo)vi.Tag;
// スレッド実行することでリストビューの描画を止めずに済む。
Task.Run(() =>
{
RequestWindowTopMost(wi.m_hWnd);
});
}
private void checkTopMost_CheckedChanged(object sender, EventArgs e)
{
this.TopMost = !this.TopMost;
}
static void RequestWindowTopMost(IntPtr hWnd)
{
#if x86
#else
IntPtr nExStyle = GetWindowLongPtr(hWnd, GWL_EXSTYLE);
#endif
long uiExStyle1 = nExStyle.ToInt64();
long uiExStyle2 = WS_EX_TOPMOST;
if ((uiExStyle1 & uiExStyle2) != 0)
{
return;
}
UInt32 uFlag = 0
| SWP_NOMOVE
| SWP_NOSIZE
;
SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, uFlag);
System.Threading.Thread.Sleep(400);
SetWindowPos(hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, uFlag | SWP_SHOWWINDOW);
}
delegate Int32 LPENUMWINDOWPROC(IntPtr hWnd, IntPtr lParam);
delegate CParamEnumWnd GETENUMWNDPARAMPROC();
private void CallEnumWindow()
{
var fnProc = new LPENUMWINDOWPROC( EnumWindowProc );
IntPtr hProc = Marshal.GetFunctionPointerForDelegate<LPENUMWINDOWPROC>(fnProc);
CParamEnumWnd param = new CParamEnumWnd();
param.m_lsWndInfo = lsWndInfo;
GETENUMWNDPARAMPROC fnProc2 = ()=>
{
return param;
};
IntPtr hProc2 = Marshal.GetFunctionPointerForDelegate<GETENUMWNDPARAMPROC>(fnProc2);
param.Setup();
EnumWindows(hProc, hProc2);
param.Cleanup();
}
private static Int32 EnumWindowProc(IntPtr hWnd, IntPtr lParam)
{
var fnGetParam = Marshal.GetDelegateForFunctionPointer<GETENUMWNDPARAMPROC>(lParam);
CParamEnumWnd param = fnGetParam();
int nCharLength;
nCharLength = GetClassName(hWnd, param.bstrClass.p, param.bstrClass.length);
String str = param.bstrClass.v.Substring(0, nCharLength);
if (str != "CabinetWClass")
{
return 1;
}
nCharLength = GetWindowText(hWnd, param.bstrTitle.p, param.bstrTitle.length);
CWndInfo wi = new CWndInfo();
wi.m_hWnd = hWnd;
wi.m_strTitle = param.bstrTitle.v.Substring(0, nCharLength);
// リストへアイテムを追加
ListViewItem vi = new ListViewItem();
vi.Text = Path.GetFileName(wi.m_strTitle);
vi.Tag = wi;
vi.Group = param.m_lsWndInfo.Groups[0];
ListViewSubItem vsi = new ListViewSubItem();
vsi.Text = Path.GetDirectoryName(wi.m_strTitle);
vi.SubItems.Add(vsi);
param.m_lsWndInfo.Items.Add(vi);
return 1;
}
class CWndInfo
{
public IntPtr m_hWnd;
public string m_strTitle;
}
class CBstr
{
IntPtr m_hStr;
int m_nCharLength;
public void Setup( String strInitValue )
{
m_hStr = Marshal.StringToBSTR(strInitValue);
m_nCharLength = strInitValue.Length;
}
public void Cleanup()
{
if (m_hStr != IntPtr.Zero)
{
Marshal.FreeBSTR(m_hStr);
m_hStr = IntPtr.Zero;
}
}
public String v
{
get
{
return Marshal.PtrToStringBSTR(m_hStr);
}
}
public IntPtr p
{
get
{
return m_hStr;
}
}
public int length
{
get { return m_nCharLength; }
}
}
class CParamEnumWnd
{
CBstr m_bstrTitle = new CBstr();
CBstr m_bstrClass = new CBstr();
public ListView m_lsWndInfo;
public void Setup()
{
String strBuffer = new String('\0', 1024);
m_bstrTitle.Setup(strBuffer);
m_bstrClass.Setup(strBuffer);
}
public void Cleanup()
{
m_bstrTitle.Cleanup();
m_bstrClass.Cleanup();
}
public CBstr bstrTitle
{
get { return m_bstrTitle; }
}
public CBstr bstrClass
{
get { return m_bstrClass; }
}
}
[DllImport("User32.dll", CharSet = CharSet.Unicode)]
public extern static Int32 GetWindowText(IntPtr hWnd, IntPtr hTitleStr, Int32 nLength);
[DllImport("User32.dll", CharSet=CharSet.Unicode)]
public extern static Int32 GetClassName(IntPtr hWnd, IntPtr hClassStr, Int32 nLength);
[DllImport("User32.dll")]
public extern static Int32 EnumWindows(IntPtr hEnumWindowProc, IntPtr lParam);
[DllImport("User32.dll")]
public extern static Int32 SetWindowPos(IntPtr hWnd, IntPtr hInsertWnd, Int32 x, Int32 y, Int32 w, Int32 h, UInt32 uFlag);
public static readonly IntPtr HWND_NOTOPMOST = new IntPtr(-2);
public static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);
public const uint SWP_NOMOVE = 0x0002;
public const uint SWP_NOSIZE = 0x0001;
public const uint SWP_SHOWWINDOW = 0x0040;
#if x86
#else
[DllImport("User32.dll")]
public extern static IntPtr GetWindowLongPtr(IntPtr hWnd, Int32 n);
#endif
public const uint WS_EX_TOPMOST = 0x00000008;
public const Int32 GWL_EXSTYLE = -20;
}