protected override void WndProc(ref Message m) {
try {
if (m.Msg == (Int32)WM.WM_PARENTNOTIFY && User32.LOWORD((Int32)m.WParam) == (Int32)WM.WM_MBUTTONDOWN) OnItemMiddleClick();
base.WndProc(ref m);
if (m.Msg == ShellNotifications.WM_SHNOTIFY) {
this.ProcessShellNotifications(ref m);
}
#region m.Msg == 78
if (m.Msg == 78) {
#region Starting
var nmhdrHeader = (NMHEADER)(m.GetLParam(typeof(NMHEADER)));
if (nmhdrHeader.hdr.code == (Int32)HDN.HDN_DROPDOWN)
Column_OnClick(nmhdrHeader.iItem);
//F.MessageBox.Show(nmhdrHeader.iItem.ToString());
else if (nmhdrHeader.hdr.code == (Int32)HDN.HDN_BEGINTRACKW)
if (this.View != ShellViewStyle.Details) m.Result = (IntPtr)1;
/*
else if (nmhdrHeader.hdr.code == (int)HDN.HDN_BEGINTRACKW)
if (this.View != ShellViewStyle.Details) m.Result = (IntPtr)1;
*/
#endregion Starting
var nmhdr = (NMHDR)m.GetLParam(typeof(NMHDR));
switch (nmhdr.code) {
case WNM.LVN_GETEMPTYMARKUP:
if (this._IsDisplayEmptyText) {
var nmlvem = (NMLVEMPTYMARKUP)m.GetLParam(typeof(NMLVEMPTYMARKUP));
nmlvem.dwFlags = 0x1;
nmlvem.szMarkup = "Working on it...";
Marshal.StructureToPtr(nmlvem, m.LParam, false);
m.Result = (IntPtr)1;
} else {
m.Result = IntPtr.Zero;
}
break;
case WNM.LVN_ENDLABELEDITW:
#region Case
var nmlvedit = (NMLVDISPINFO)m.GetLParam(typeof(NMLVDISPINFO));
if (!String.IsNullOrEmpty(nmlvedit.item.pszText)) {
var item = this.Items[nmlvedit.item.iItem];
RenameShellItem(item.ComInterface, nmlvedit.item.pszText, (item.DisplayName != Path.GetFileName(item.ParsingName)) && !item.IsFolder, item.Extension);
this.EndLabelEdit();
}
this._EditorSubclass?.DestroyHandle();
break;
#endregion Case
case WNM.LVN_GETDISPINFOW:
#region Case
var nmlv = (NMLVDISPINFO)m.GetLParam(typeof(NMLVDISPINFO));
if (Items.Count == 0 || Items.Count - 1 < nmlv.item.iItem)
break;
var currentItem = this.IsSearchNavigating ? Items[nmlv.item.iItem].Clone() : Items[nmlv.item.iItem];
if ((nmlv.item.mask & LVIF.LVIF_TEXT) == LVIF.LVIF_TEXT) {
if (nmlv.item.iSubItem == 0) {
nmlv.item.pszText = currentItem.DisplayName;
Marshal.StructureToPtr(nmlv, m.LParam, false);
} else {
if ((View == ShellViewStyle.List || View == ShellViewStyle.SmallIcon || View == ShellViewStyle.Details) || (this.View == ShellViewStyle.Tile && this.AllAvailableColumns.Count >= nmlv.item.iSubItem)) {
var currentCollumn = this.View == ShellViewStyle.Tile
? this.AllAvailableColumns.Values.ToArray()[nmlv.item.iSubItem]
: this.Collumns[nmlv.item.iSubItem];
Object valueCached;
if (currentItem.ColumnValues.TryGetValue(currentCollumn.pkey, out valueCached)) {
String val = String.Empty;
if (valueCached != null) {
if (currentCollumn.CollumnType == typeof(DateTime))
val = ((DateTime)valueCached).ToString(Thread.CurrentThread.CurrentUICulture);
else if (currentCollumn.CollumnType == typeof(Int64))
val = $"{Math.Ceiling(Convert.ToDouble(valueCached.ToString()) / 1024):# ### ### ##0} KB";
else if (currentCollumn.CollumnType == typeof(PerceivedType))
val = ((PerceivedType)valueCached).ToString();
else if (currentCollumn.CollumnType == typeof(FileAttributes))
val = this.GetFilePropertiesString(valueCached);
else
val = valueCached.ToString();
}
nmlv.item.pszText = val.Trim();
} else {
var temp = currentItem;
var isi2 = (IShellItem2)temp.ComInterface;
var guid = new Guid(InterfaceGuids.IPropertyStore);
IPropertyStore propStore = null;
isi2.GetPropertyStore(GetPropertyStoreOptions.FastPropertiesOnly, ref guid, out propStore);
PROPERTYKEY pk = currentCollumn.pkey;
var pvar = new PropVariant();
if (propStore != null && propStore.GetValue(ref pk, pvar) == HResult.S_OK) {
if (pvar.Value == null) {
if (this.IconSize == 16) {
this.SmallImageList.EnqueueSubitemsGet(Tuple.Create(nmlv.item.iItem, nmlv.item.iSubItem, pk));
} else {
this.LargeImageList.EnqueueSubitemsGet(Tuple.Create(nmlv.item.iItem, nmlv.item.iSubItem, pk));
}
} else {
var val = String.Empty;
if (currentCollumn.CollumnType == typeof(DateTime))
val = ((DateTime)pvar.Value).ToString(Thread.CurrentThread.CurrentUICulture);
else if (currentCollumn.CollumnType == typeof(Int64))
val =
$"{Math.Ceiling(Convert.ToDouble(pvar.Value.ToString()) / 1024):# ### ### ##0} KB";
else if (currentCollumn.CollumnType == typeof(PerceivedType))
val = ((PerceivedType)pvar.Value).ToString();
else if (currentCollumn.CollumnType == typeof(FileAttributes))
val = this.GetFilePropertiesString(pvar.Value);
else
val = pvar.Value.ToString();
nmlv.item.pszText = val.Trim();
pvar.Dispose();
}
}
}
}
Marshal.StructureToPtr(nmlv, m.LParam, false);
}
}
if ((nmlv.item.mask & LVIF.LVIF_COLUMNS) == LVIF.LVIF_COLUMNS && this.CurrentFolder?.ParsingName.Equals(KnownFolders.Computer.ParsingName) == false) {
int[] columns = null;
var refGuidPDL = typeof(IPropertyDescriptionList).GUID;
var refGuidPD = typeof(IPropertyDescription).GUID;
var iShellItem2 = (IShellItem2)currentItem.ComInterface;
var ptrPDL = IntPtr.Zero;
iShellItem2.GetPropertyDescriptionList(SpecialProperties.PropListTileInfo, ref refGuidPDL,
out ptrPDL);
IPropertyDescriptionList propertyDescriptionList = (IPropertyDescriptionList)Marshal.GetObjectForIUnknown(ptrPDL);
var descriptionsCount = 0u;
propertyDescriptionList.GetCount(out descriptionsCount);
nmlv.item.cColumns = (int)descriptionsCount;
columns = new int[nmlv.item.cColumns];
Marshal.Copy(nmlv.item.puColumns, columns, 0, nmlv.item.cColumns);
for (uint i = 0; i < descriptionsCount; i++) {
IPropertyDescription propertyDescription = null;
propertyDescriptionList.GetAt(i, ref refGuidPD, out propertyDescription);
PROPERTYKEY pkey;
propertyDescription.GetPropertyKey(out pkey);
Collumns column = null;
if (this.AllAvailableColumns.TryGetValue(pkey, out column)) {
columns[i] = column.Index;
} else {
columns[i] = 0;
}
}
Marshal.Copy(columns, 0, nmlv.item.puColumns, nmlv.item.cColumns);
Marshal.StructureToPtr(nmlv, m.LParam, false);
}
break;
#endregion Case
case WNM.LVN_COLUMNCLICK:
#region Case
var nlcv = (NMLISTVIEW)m.GetLParam(typeof(NMLISTVIEW));
var sortOrder = SortOrder.Ascending;
if (this.LastSortedColumnId == this.Collumns[nlcv.iSubItem].ID) {
sortOrder = this.LastSortOrder == SortOrder.Ascending ? SortOrder.Descending : SortOrder.Ascending;
}
if (!this.IsGroupsEnabled) {
SetSortCollumn(true, this.Collumns[nlcv.iSubItem], sortOrder);
} else if (this.LastGroupCollumn == this.Collumns[nlcv.iSubItem]) {
this.SetGroupOrder();
} else {
SetSortCollumn(true, this.Collumns[nlcv.iSubItem], sortOrder);
this.SetGroupOrder(false);
}
break;
#endregion Case
case WNM.LVN_GETINFOTIP:
#region Case
var nmGetInfoTip = (NMLVGETINFOTIP)m.GetLParam(typeof(NMLVGETINFOTIP));
if (this.Items.Count == 0)
break;
if (ToolTip == null)
ToolTip = new ToolTip(this);
var itemInfotip = this.Items[nmGetInfoTip.iItem];
Char[] charBuf = ("\0").ToCharArray();
Marshal.Copy(charBuf, 0, nmGetInfoTip.pszText, Math.Min(charBuf.Length, nmGetInfoTip.cchTextMax));
Marshal.StructureToPtr(nmGetInfoTip, m.LParam, false);
if (ToolTip.IsVisible)
ToolTip.HideTooltip();
ToolTip.CurrentItem = itemInfotip;
ToolTip.ItemIndex = nmGetInfoTip.iItem;
ToolTip.Type = nmGetInfoTip.dwFlags;
ToolTip.Left = -500;
ToolTip.Top = -500;
ToolTip.ShowTooltip();
break;
#endregion Case
case WNM.LVN_ODFINDITEM:
#region Case
if (this.ToolTip != null && this.ToolTip.IsVisible)
this.ToolTip.HideTooltip();
var findItem = (NMLVFINDITEM)m.GetLParam(typeof(NMLVFINDITEM));
KeyJumpString = findItem.lvfi.psz;
KeyJumpKeyDown?.Invoke(this, new KeyEventArgs(Keys.A));
Int32 startindex = this.GetFirstSelectedItemIndex() + (KeyJumpString.Length > 1 ? 0 : 1);
Int32 selind = GetFirstIndexOf(KeyJumpString, startindex);
if (selind != -1) {
m.Result = (IntPtr)(selind);
if (IsGroupsEnabled)
this.SelectItemByIndex(selind, true, true);
} else {
int selindOver = GetFirstIndexOf(KeyJumpString, 0);
if (selindOver != -1) {
m.Result = (IntPtr)(selindOver);
if (IsGroupsEnabled)
this.SelectItemByIndex(selindOver, true, true);
}
}
break;
#endregion Case
case -175:
#region Case
var nmlvLe = (NMLVDISPINFO)m.GetLParam(typeof(NMLVDISPINFO));
if (this.ToolTip != null && this.ToolTip.IsVisible)
this.ToolTip.HideTooltip();
this.IsFocusAllowed = false;
this._IsCanceledOperation = false;
this._ItemForRename = nmlvLe.item.iItem;
this.BeginItemLabelEdit?.Invoke(this, new RenameEventArgs(this._ItemForRename));
m.Result = (IntPtr)0;
var editControl = User32.SendMessage(this.LVHandle, 0x1018, 0, 0);
var indexLastDot = this.Items[this._ItemForRename].DisplayName.LastIndexOf(".", StringComparison.Ordinal);
User32.SendMessage(editControl, 0x00B1, 0, indexLastDot);
break;
#endregion Case
case WNM.LVN_ITEMACTIVATE:
#region Case
if (this.ToolTip != null && this.ToolTip.IsVisible) this.ToolTip.HideTooltip();
if (_ItemForRealNameIsAny && this.IsRenameInProgress) {
this.EndLabelEdit();
} else {
var iac = (NMITEMACTIVATE)m.GetLParam(typeof(NMITEMACTIVATE));
var selectedItem = Items[iac.iItem];
if (selectedItem.IsFolder) {
Navigate_Full(selectedItem, true);
} else if (selectedItem.IsLink || selectedItem.ParsingName.EndsWith(".lnk")) {
var shellLink = new ShellLink(selectedItem.ParsingName);
var newSho = FileSystemListItem.ToFileSystemItem(this.LVHandle, shellLink.TargetPIDL);
if (newSho.IsFolder)
Navigate_Full(newSho, true);
} else {
StartProcessInCurrentDirectory(selectedItem);
}
}
break;
#endregion Case
case WNM.LVN_BEGINSCROLL:
#region Case
this.EndLabelEdit();
this.LargeImageList.ResetEvent.Reset();
_ResetEvent.Reset();
_ResetTimer.Stop();
this.ToolTip?.HideTooltip();
break;
#endregion Case
case WNM.LVN_ENDSCROLL:
#region Case
_ResetTimer.Start();
//this.resetEvent.Set();
break;
#endregion Case
case -100:
#region Case
F.MessageBox.Show("AM");
break;
#endregion Case
case WNM.LVN_ITEMCHANGED:
#region Case
var nlv = (NMLISTVIEW)m.GetLParam(typeof(NMLISTVIEW));
if ((nlv.uChanged & LVIF.LVIF_STATE) == LVIF.LVIF_STATE) {
this._IsDragSelect = nlv.uNewState;
if (nlv.iItem != _LastItemForRename)
_LastItemForRename = -1;
if (!_SelectionTimer.Enabled)
_SelectionTimer.Start();
}
break;
#endregion Case
case WNM.LVN_ODSTATECHANGED:
#region Case
OnSelectionChanged();
break;
#endregion Case
case WNM.LVN_KEYDOWN:
#region Case
var nkd = (NMLVKEYDOWN)m.GetLParam(typeof(NMLVKEYDOWN));
if (!ShellView_KeyDown((Keys)((int)nkd.wVKey))) {
m.Result = (IntPtr)1;
break;
}
if (nkd.wVKey == (short)Keys.F2 && !(System.Windows.Input.Keyboard.FocusedElement is System.Windows.Controls.TextBox)) {
RenameSelectedItem();
}
if (!_ItemForRealNameIsAny && !this.IsRenameInProgress && !(System.Windows.Input.Keyboard.FocusedElement is System.Windows.Controls.TextBox)) {
switch (nkd.wVKey) {
case (short)Keys.Enter:
if (this._IsCanceledOperation) {
//this.IsRenameInProgress = false;
break;
}
var selectedItem = this.GetFirstSelectedItem();
if (selectedItem.IsFolder) {
Navigate(selectedItem, false, false, this.IsNavigationInProgress);
} else if (selectedItem.IsLink && selectedItem.ParsingName.EndsWith(".lnk")) {
var shellLink = new ShellLink(selectedItem.ParsingName);
var newSho = new FileSystemListItem();
newSho.Initialize(this.LVHandle, shellLink.TargetPIDL);
if (newSho.IsFolder)
Navigate(newSho, false, false, this.IsNavigationInProgress);
else
StartProcessInCurrentDirectory(newSho);
shellLink.Dispose();
} else {
StartProcessInCurrentDirectory(selectedItem);
}
break;
}
this.Focus();
} else {
switch (nkd.wVKey) {
case (Int16)Keys.Enter:
if (!this.IsRenameInProgress)
this.EndLabelEdit();
this.Focus();
break;
case (Int16)Keys.Escape:
this.EndLabelEdit(true);
this.Focus();
break;
default:
break;
}
if (System.Windows.Input.Keyboard.FocusedElement is System.Windows.Controls.TextBox) {
m.Result = (IntPtr)1;
break;
}
}
break;
#endregion Case
case WNM.LVN_GROUPINFO: //TODO: Deal with this useless code
#region Case
//RedrawWindow();
break;
#endregion Case
case WNM.LVN_HOTTRACK:
#region Case
var nlvHotTrack = (NMLISTVIEW)m.GetLParam(typeof(NMLISTVIEW));
if (ToolTip != null && nlvHotTrack.iItem != ToolTip.ItemIndex && ToolTip.ItemIndex > -1) {
ToolTip.HideTooltip();
this.Focus();
}
break;
#endregion Case
case WNM.LVN_BEGINDRAG:
#region Case
this._DraggedItemIndexes.Clear();
var dataObjPtr = IntPtr.Zero;
_DataObject = this.SelectedItems.ToArray().GetIDataObject(out dataObjPtr);
//uint ef = 0;
var ishell2 = (DataObject.IDragSourceHelper2)new DragDropHelper();
ishell2.SetFlags(1);
var wp = new DataObject.Win32Point() { X = Cursor.Position.X, Y = Cursor.Position.Y };
ishell2.InitializeFromWindow(this.Handle, ref wp, _DataObject);
DoDragDrop(_DataObject, F.DragDropEffects.All | F.DragDropEffects.Link);
//Shell32.SHDoDragDrop(this.Handle, dataObject, null, unchecked((uint)F.DragDropEffects.All | (uint)F.DragDropEffects.Link), out ef);
break;
#endregion Case
case WNM.NM_RCLICK:
#region Case
var nmhdrHdn = (NMHEADER)(m.GetLParam(typeof(NMHEADER)));
var itemActivate = (NMITEMACTIVATE)m.GetLParam(typeof(NMITEMACTIVATE));
this.ToolTip?.HideTooltip();
if (nmhdrHdn.iItem != -1 && nmhdrHdn.hdr.hwndFrom == this.LVHandle) {
//Workaround for cases where on right click over an ites the item is not actually selected
if (this.GetSelectedCount() == 0) {
this.SelectItemByIndex(nmhdrHdn.iItem);
}
var selitems = this.SelectedItems;
var cm = new ShellContextMenu(selitems.ToArray(), SVGIO.SVGIO_SELECTION, this);
cm.ShowContextMenu(this, itemActivate.ptAction, CMF.CANRENAME);
} else if (nmhdrHdn.iItem == -1) {
var cm = new ShellContextMenu(new IListItemEx[1] { this.CurrentFolder }, SVGIO.SVGIO_BACKGROUND, this);
cm.ShowContextMenu(this, itemActivate.ptAction, 0, true);
} else {
this.ColumnHeaderRightClick?.Invoke(this, new MouseEventArgs(F.MouseButtons.Right, 1, MousePosition.X, MousePosition.Y, 0));
}
break;
#endregion Case
case WNM.NM_CLICK: //TODO: Deal with this useless code
#region Case
break;
#endregion Case
case WNM.NM_SETFOCUS:
#region Case
if (IsGroupsEnabled)
RedrawWindow();
ShellView_GotFocus();
this.IsFocusAllowed = true;
break;
#endregion Case
case WNM.NM_KILLFOCUS:
#region Case
if (this._ItemForRename != -1 && !this.IsRenameInProgress)
EndLabelEdit();
if (IsGroupsEnabled)
RedrawWindow();
this.ToolTip?.HideTooltip();
//OnLostFocus();
if (this.IsRenameInProgress) {
this.Focus(false);
}
break;
#endregion Case
case CustomDraw.NM_CUSTOMDRAW:
this.ProcessCustomDraw(ref m, ref nmhdr);
break;
}
}
#endregion m.Msg == 78
} catch {
}
}