mirror of
https://github.com/mirror/processhacker
synced 2026-06-08 16:03:24 +00:00
* added copy support to PE viewer
* moved cpysave to phlib git-svn-id: svn://svn.code.sf.net/p/processhacker/code@4115 21ef857c-d57f-4fe0-8362-d861dc6d29cd
This commit is contained in:
@@ -2,6 +2,7 @@ Process Hacker
|
||||
|
||||
2.13
|
||||
* NEW/IMPROVED:
|
||||
* Added copy support to PE viewer
|
||||
* FIXED:
|
||||
|
||||
2.12
|
||||
|
||||
@@ -222,6 +222,7 @@
|
||||
<ClCompile Include="..\phlib\circbuf.c" />
|
||||
<ClCompile Include="..\phlib\collect.c" />
|
||||
<ClCompile Include="..\phlib\colorbox.c" />
|
||||
<ClCompile Include="..\phlib\cpysave.c" />
|
||||
<ClCompile Include="..\phlib\data.c" />
|
||||
<ClCompile Include="..\phlib\dspick.c" />
|
||||
<ClCompile Include="..\phlib\emenu.c" />
|
||||
@@ -266,7 +267,6 @@
|
||||
<ClCompile Include="chdlg.c" />
|
||||
<ClCompile Include="chproc.c" />
|
||||
<ClCompile Include="cmdmode.c" />
|
||||
<ClCompile Include="cpysave.c" />
|
||||
<ClCompile Include="dbgcon.c" />
|
||||
<ClCompile Include="findobj.c" />
|
||||
<ClCompile Include="gdihndl.c" />
|
||||
|
||||
@@ -177,9 +177,6 @@
|
||||
<ClCompile Include="cmdmode.c">
|
||||
<Filter>Process Hacker</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="cpysave.c">
|
||||
<Filter>Process Hacker</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="dbgcon.c">
|
||||
<Filter>Process Hacker</Filter>
|
||||
</ClCompile>
|
||||
@@ -435,6 +432,9 @@
|
||||
<ClCompile Include="sessshad.c">
|
||||
<Filter>Process Hacker</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\phlib\cpysave.c">
|
||||
<Filter>phlib</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\phlib\circbuf_i.h">
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
#include <phapp.h>
|
||||
#include <settings.h>
|
||||
#include <cpysave.h>
|
||||
#include "mxml/mxml.h"
|
||||
#include <winsta.h>
|
||||
#include <dbghelp.h>
|
||||
|
||||
@@ -1150,39 +1150,6 @@ BOOLEAN PhShowChooseProcessDialog(
|
||||
__out PHANDLE ProcessId
|
||||
);
|
||||
|
||||
// cpysave
|
||||
|
||||
#define PH_EXPORT_MODE_TABS 0
|
||||
#define PH_EXPORT_MODE_SPACES 1
|
||||
#define PH_EXPORT_MODE_CSV 2
|
||||
|
||||
PHAPPAPI
|
||||
PPH_FULL_STRING PhGetTreeListText(
|
||||
__in HWND TreeListHandle,
|
||||
__in ULONG MaximumNumberOfColumns
|
||||
);
|
||||
|
||||
PPH_LIST PhGetProcessTreeListLines(
|
||||
__in HWND TreeListHandle,
|
||||
__in ULONG NumberOfNodes,
|
||||
__in PPH_LIST RootNodes,
|
||||
__in ULONG Mode
|
||||
);
|
||||
|
||||
PPH_LIST PhGetGenericTreeListLines(
|
||||
__in HWND TreeListHandle,
|
||||
__in ULONG Mode
|
||||
);
|
||||
|
||||
PPH_FULL_STRING PhGetListViewText(
|
||||
__in HWND ListViewHandle
|
||||
);
|
||||
|
||||
PPH_LIST PhGetListViewLines(
|
||||
__in HWND ListViewHandle,
|
||||
__in ULONG Mode
|
||||
);
|
||||
|
||||
// findobj
|
||||
|
||||
VOID PhShowFindObjectsDialog();
|
||||
|
||||
@@ -303,6 +303,13 @@ VOID PhRemoveProcessTreeFilter(
|
||||
PHAPPAPI
|
||||
VOID PhApplyProcessTreeFilters();
|
||||
|
||||
PPH_LIST PhGetProcessTreeListLines(
|
||||
__in HWND TreeListHandle,
|
||||
__in ULONG NumberOfNodes,
|
||||
__in PPH_LIST RootNodes,
|
||||
__in ULONG Mode
|
||||
);
|
||||
|
||||
VOID PhCopyProcessTree();
|
||||
|
||||
VOID PhWriteProcessTree(
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <phapp.h>
|
||||
#include <treelist.h>
|
||||
#include <settings.h>
|
||||
#include <cpysave.h>
|
||||
#include <memsrch.h>
|
||||
#include <symprv.h>
|
||||
#include <emenu.h>
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <procprpp.h>
|
||||
#include <kphuser.h>
|
||||
#include <settings.h>
|
||||
#include <cpysave.h>
|
||||
#include <emenu.h>
|
||||
#include <phplug.h>
|
||||
#include <windowsx.h>
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <phapp.h>
|
||||
#include <settings.h>
|
||||
#include <phplug.h>
|
||||
#include <cpysave.h>
|
||||
|
||||
VOID PhpEnableColumnCustomDraw(
|
||||
__in HWND hwnd,
|
||||
@@ -2131,6 +2132,125 @@ VOID PhApplyProcessTreeFilters()
|
||||
TreeList_NodesStructured(ProcessTreeListHandle);
|
||||
}
|
||||
|
||||
VOID PhpPopulateTableWithProcessNodes(
|
||||
__in HWND TreeListHandle,
|
||||
__in PPH_PROCESS_NODE Node,
|
||||
__in ULONG Level,
|
||||
__in PPH_STRING **Table,
|
||||
__inout PULONG Index,
|
||||
__in PULONG DisplayToId,
|
||||
__in ULONG Columns
|
||||
)
|
||||
{
|
||||
ULONG i;
|
||||
|
||||
for (i = 0; i < Columns; i++)
|
||||
{
|
||||
PH_TL_GETNODETEXT getNodeText;
|
||||
PPH_STRING text;
|
||||
|
||||
getNodeText.Node = &Node->Node;
|
||||
getNodeText.Id = DisplayToId[i];
|
||||
PhInitializeEmptyStringRef(&getNodeText.Text);
|
||||
TreeList_GetNodeText(TreeListHandle, &getNodeText);
|
||||
|
||||
if (i != 0)
|
||||
{
|
||||
text = PhaCreateStringEx(getNodeText.Text.Buffer, getNodeText.Text.Length);
|
||||
}
|
||||
else
|
||||
{
|
||||
// If this is the first column in the row, add some indentation.
|
||||
text = PhaCreateStringEx(
|
||||
NULL,
|
||||
getNodeText.Text.Length + Level * 2 * sizeof(WCHAR)
|
||||
);
|
||||
wmemset(text->Buffer, ' ', Level * 2);
|
||||
memcpy(&text->Buffer[Level * 2], getNodeText.Text.Buffer, getNodeText.Text.Length);
|
||||
}
|
||||
|
||||
Table[*Index][i] = text;
|
||||
}
|
||||
|
||||
(*Index)++;
|
||||
|
||||
// Process the children.
|
||||
for (i = 0; i < Node->Children->Count; i++)
|
||||
{
|
||||
PhpPopulateTableWithProcessNodes(
|
||||
TreeListHandle,
|
||||
Node->Children->Items[i],
|
||||
Level + 1,
|
||||
Table,
|
||||
Index,
|
||||
DisplayToId,
|
||||
Columns
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
PPH_LIST PhGetProcessTreeListLines(
|
||||
__in HWND TreeListHandle,
|
||||
__in ULONG NumberOfNodes,
|
||||
__in PPH_LIST RootNodes,
|
||||
__in ULONG Mode
|
||||
)
|
||||
{
|
||||
PH_AUTO_POOL autoPool;
|
||||
PPH_LIST lines;
|
||||
// The number of rows in the table (including +1 for the column headers).
|
||||
ULONG rows;
|
||||
// The number of columns.
|
||||
ULONG columns;
|
||||
// A column display index to ID map.
|
||||
ULONG displayToId[PHPRTLC_MAXIMUM];
|
||||
// A column display index to text map.
|
||||
PWSTR displayToText[PHPRTLC_MAXIMUM];
|
||||
// The actual string table.
|
||||
PPH_STRING **table;
|
||||
ULONG i;
|
||||
ULONG j;
|
||||
|
||||
// Use a local auto-pool to make memory mangement a bit less painful.
|
||||
PhInitializeAutoPool(&autoPool);
|
||||
|
||||
rows = NumberOfNodes + 1;
|
||||
|
||||
// Create the display index to ID map.
|
||||
PhMapDisplayIndexTreeList(TreeListHandle, PHPRTLC_MAXIMUM, displayToId, displayToText, &columns);
|
||||
|
||||
PhaCreateTextTable(&table, rows, columns);
|
||||
|
||||
// Populate the first row with the column headers.
|
||||
for (i = 0; i < columns; i++)
|
||||
{
|
||||
table[0][i] = PhaCreateString(displayToText[i]);
|
||||
}
|
||||
|
||||
// Go through the nodes in the process tree and populate each cell of the table.
|
||||
|
||||
j = 1; // index starts at one because the first row contains the column headers.
|
||||
|
||||
for (i = 0; i < RootNodes->Count; i++)
|
||||
{
|
||||
PhpPopulateTableWithProcessNodes(
|
||||
TreeListHandle,
|
||||
RootNodes->Items[i],
|
||||
0,
|
||||
table,
|
||||
&j,
|
||||
displayToId,
|
||||
columns
|
||||
);
|
||||
}
|
||||
|
||||
lines = PhaFormatTextTable(table, rows, columns, Mode);
|
||||
|
||||
PhDeleteAutoPool(&autoPool);
|
||||
|
||||
return lines;
|
||||
}
|
||||
|
||||
VOID PhCopyProcessTree()
|
||||
{
|
||||
PPH_FULL_STRING text;
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#include "treelist.h"
|
||||
#include "emenu.h"
|
||||
#include "cpysave.h"
|
||||
#include "phapppub.h"
|
||||
#include "phplug.h"
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <phapp.h>
|
||||
#include <settings.h>
|
||||
#include <phplug.h>
|
||||
#include <cpysave.h>
|
||||
|
||||
BOOLEAN PhpServiceNodeHashtableCompareFunction(
|
||||
__in PVOID Entry1,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Process Hacker -
|
||||
* copy/save code for listviews and treelists
|
||||
*
|
||||
* Copyright (C) 2010 wj32
|
||||
* Copyright (C) 2010-2011 wj32
|
||||
*
|
||||
* This file is part of Process Hacker.
|
||||
*
|
||||
@@ -20,436 +20,12 @@
|
||||
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <phapp.h>
|
||||
#include <phgui.h>
|
||||
#include <treelist.h>
|
||||
#include <cpysave.h>
|
||||
|
||||
#define TAB_SIZE 8
|
||||
|
||||
VOID PhapCreateTextTable(
|
||||
__out PPH_STRING ***Table,
|
||||
__in ULONG Rows,
|
||||
__in ULONG Columns
|
||||
);
|
||||
|
||||
PPH_LIST PhapFormatTextTable(
|
||||
__in PPH_STRING **Table,
|
||||
__in ULONG Rows,
|
||||
__in ULONG Columns,
|
||||
__in ULONG Mode
|
||||
);
|
||||
|
||||
VOID PhpMapDisplayIndexTreeList(
|
||||
__in HWND TreeListHandle,
|
||||
__in ULONG MaximumNumberOfColumns,
|
||||
__out_ecount(MaximumNumberOfColumns) PULONG DisplayToId,
|
||||
__out_ecount_opt(MaximumNumberOfColumns) PWSTR *DisplayToText,
|
||||
__out PULONG NumberOfColumns
|
||||
)
|
||||
{
|
||||
PH_TREELIST_COLUMN column;
|
||||
ULONG i;
|
||||
ULONG count;
|
||||
|
||||
count = 0;
|
||||
|
||||
for (i = 0; i < MaximumNumberOfColumns; i++)
|
||||
{
|
||||
column.Id = i;
|
||||
|
||||
if (TreeList_GetColumn(TreeListHandle, &column))
|
||||
{
|
||||
if (column.Visible)
|
||||
{
|
||||
if (column.DisplayIndex < MaximumNumberOfColumns)
|
||||
{
|
||||
DisplayToId[column.DisplayIndex] = i;
|
||||
|
||||
if (DisplayToText)
|
||||
DisplayToText[column.DisplayIndex] = column.Text;
|
||||
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*NumberOfColumns = count;
|
||||
}
|
||||
|
||||
PPH_FULL_STRING PhGetTreeListText(
|
||||
__in HWND TreeListHandle,
|
||||
__in ULONG MaximumNumberOfColumns
|
||||
)
|
||||
{
|
||||
PPH_FULL_STRING string;
|
||||
PULONG displayToId;
|
||||
ULONG rows;
|
||||
ULONG columns;
|
||||
ULONG i;
|
||||
ULONG j;
|
||||
|
||||
displayToId = PhAllocate(MaximumNumberOfColumns * sizeof(ULONG));
|
||||
|
||||
PhpMapDisplayIndexTreeList(TreeListHandle, MaximumNumberOfColumns, displayToId, NULL, &columns);
|
||||
rows = TreeList_GetVisibleNodeCount(TreeListHandle);
|
||||
|
||||
string = PhCreateFullString2(0x100);
|
||||
|
||||
for (i = 0; i < rows; i++)
|
||||
{
|
||||
PH_TL_GETNODETEXT getNodeText;
|
||||
|
||||
getNodeText.Node = TreeList_GetVisibleNode(TreeListHandle, i);
|
||||
assert(getNodeText.Node);
|
||||
|
||||
if (!getNodeText.Node->Selected)
|
||||
continue;
|
||||
|
||||
for (j = 0; j < columns; j++)
|
||||
{
|
||||
getNodeText.Id = displayToId[j];
|
||||
PhInitializeEmptyStringRef(&getNodeText.Text);
|
||||
TreeList_GetNodeText(TreeListHandle, &getNodeText);
|
||||
|
||||
PhAppendFullStringEx(string, getNodeText.Text.Buffer, getNodeText.Text.Length);
|
||||
PhAppendFullString2(string, L", ");
|
||||
}
|
||||
|
||||
// Remove the trailing comma and space.
|
||||
if (string->Length != 0)
|
||||
PhRemoveFullString(string, string->Length / 2 - 2, 2);
|
||||
|
||||
PhAppendFullString2(string, L"\r\n");
|
||||
}
|
||||
|
||||
PhFree(displayToId);
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
VOID PhpPopulateTableWithProcessNodes(
|
||||
__in HWND TreeListHandle,
|
||||
__in PPH_PROCESS_NODE Node,
|
||||
__in ULONG Level,
|
||||
__in PPH_STRING **Table,
|
||||
__inout PULONG Index,
|
||||
__in PULONG DisplayToId,
|
||||
__in ULONG Columns
|
||||
)
|
||||
{
|
||||
ULONG i;
|
||||
|
||||
for (i = 0; i < Columns; i++)
|
||||
{
|
||||
PH_TL_GETNODETEXT getNodeText;
|
||||
PPH_STRING text;
|
||||
|
||||
getNodeText.Node = &Node->Node;
|
||||
getNodeText.Id = DisplayToId[i];
|
||||
PhInitializeEmptyStringRef(&getNodeText.Text);
|
||||
TreeList_GetNodeText(TreeListHandle, &getNodeText);
|
||||
|
||||
if (i != 0)
|
||||
{
|
||||
text = PhaCreateStringEx(getNodeText.Text.Buffer, getNodeText.Text.Length);
|
||||
}
|
||||
else
|
||||
{
|
||||
// If this is the first column in the row, add some indentation.
|
||||
text = PhaCreateStringEx(
|
||||
NULL,
|
||||
getNodeText.Text.Length + Level * 2 * sizeof(WCHAR)
|
||||
);
|
||||
wmemset(text->Buffer, ' ', Level * 2);
|
||||
memcpy(&text->Buffer[Level * 2], getNodeText.Text.Buffer, getNodeText.Text.Length);
|
||||
}
|
||||
|
||||
Table[*Index][i] = text;
|
||||
}
|
||||
|
||||
(*Index)++;
|
||||
|
||||
// Process the children.
|
||||
for (i = 0; i < Node->Children->Count; i++)
|
||||
{
|
||||
PhpPopulateTableWithProcessNodes(
|
||||
TreeListHandle,
|
||||
Node->Children->Items[i],
|
||||
Level + 1,
|
||||
Table,
|
||||
Index,
|
||||
DisplayToId,
|
||||
Columns
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
PPH_LIST PhGetProcessTreeListLines(
|
||||
__in HWND TreeListHandle,
|
||||
__in ULONG NumberOfNodes,
|
||||
__in PPH_LIST RootNodes,
|
||||
__in ULONG Mode
|
||||
)
|
||||
{
|
||||
PH_AUTO_POOL autoPool;
|
||||
PPH_LIST lines;
|
||||
// The number of rows in the table (including +1 for the column headers).
|
||||
ULONG rows;
|
||||
// The number of columns.
|
||||
ULONG columns;
|
||||
// A column display index to ID map.
|
||||
ULONG displayToId[PHPRTLC_MAXIMUM];
|
||||
// A column display index to text map.
|
||||
PWSTR displayToText[PHPRTLC_MAXIMUM];
|
||||
// The actual string table.
|
||||
PPH_STRING **table;
|
||||
ULONG i;
|
||||
ULONG j;
|
||||
|
||||
// Use a local auto-pool to make memory mangement a bit less painful.
|
||||
PhInitializeAutoPool(&autoPool);
|
||||
|
||||
rows = NumberOfNodes + 1;
|
||||
|
||||
// Create the display index to ID map.
|
||||
PhpMapDisplayIndexTreeList(TreeListHandle, PHPRTLC_MAXIMUM, displayToId, displayToText, &columns);
|
||||
|
||||
PhapCreateTextTable(&table, rows, columns);
|
||||
|
||||
// Populate the first row with the column headers.
|
||||
for (i = 0; i < columns; i++)
|
||||
{
|
||||
table[0][i] = PhaCreateString(displayToText[i]);
|
||||
}
|
||||
|
||||
// Go through the nodes in the process tree and populate each cell of the table.
|
||||
|
||||
j = 1; // index starts at one because the first row contains the column headers.
|
||||
|
||||
for (i = 0; i < RootNodes->Count; i++)
|
||||
{
|
||||
PhpPopulateTableWithProcessNodes(
|
||||
TreeListHandle,
|
||||
RootNodes->Items[i],
|
||||
0,
|
||||
table,
|
||||
&j,
|
||||
displayToId,
|
||||
columns
|
||||
);
|
||||
}
|
||||
|
||||
lines = PhapFormatTextTable(table, rows, columns, Mode);
|
||||
|
||||
PhDeleteAutoPool(&autoPool);
|
||||
|
||||
return lines;
|
||||
}
|
||||
|
||||
PPH_LIST PhGetGenericTreeListLines(
|
||||
__in HWND TreeListHandle,
|
||||
__in ULONG Mode
|
||||
)
|
||||
{
|
||||
PH_AUTO_POOL autoPool;
|
||||
PPH_LIST lines;
|
||||
ULONG rows;
|
||||
ULONG columns;
|
||||
ULONG numberOfNodes;
|
||||
ULONG maxId;
|
||||
PULONG displayToId;
|
||||
PWSTR *displayToText;
|
||||
PPH_STRING **table;
|
||||
ULONG i;
|
||||
ULONG j;
|
||||
|
||||
PhInitializeAutoPool(&autoPool);
|
||||
|
||||
numberOfNodes = TreeList_GetVisibleNodeCount(TreeListHandle);
|
||||
maxId = TreeList_GetMaxId(TreeListHandle) + 1;
|
||||
displayToId = PhAllocate(sizeof(ULONG) * maxId);
|
||||
displayToText = PhAllocate(sizeof(PWSTR) * maxId);
|
||||
|
||||
rows = numberOfNodes + 1;
|
||||
PhpMapDisplayIndexTreeList(TreeListHandle, maxId, displayToId, displayToText, &columns);
|
||||
|
||||
PhapCreateTextTable(&table, rows, columns);
|
||||
|
||||
for (i = 0; i < columns; i++)
|
||||
table[0][i] = PhaCreateString(displayToText[i]);
|
||||
|
||||
for (i = 0; i < numberOfNodes; i++)
|
||||
{
|
||||
PPH_TREELIST_NODE node;
|
||||
|
||||
node = TreeList_GetVisibleNode(TreeListHandle, i);
|
||||
|
||||
if (node)
|
||||
{
|
||||
for (j = 0; j < columns; j++)
|
||||
{
|
||||
PH_TL_GETNODETEXT getNodeText;
|
||||
|
||||
getNodeText.Node = node;
|
||||
getNodeText.Id = displayToId[j];
|
||||
PhInitializeEmptyStringRef(&getNodeText.Text);
|
||||
TreeList_GetNodeText(TreeListHandle, &getNodeText);
|
||||
|
||||
table[i + 1][j] = PhaCreateStringEx(getNodeText.Text.Buffer, getNodeText.Text.Length);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (j = 0; j < columns; j++)
|
||||
{
|
||||
table[i + 1][j] = PHA_DEREFERENCE(PhReferenceEmptyString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PhFree(displayToText);
|
||||
PhFree(displayToId);
|
||||
|
||||
lines = PhapFormatTextTable(table, rows, columns, Mode);
|
||||
|
||||
PhDeleteAutoPool(&autoPool);
|
||||
|
||||
return lines;
|
||||
}
|
||||
|
||||
VOID PhapMapDisplayIndexListView(
|
||||
__in HWND ListViewHandle,
|
||||
__out_ecount(Count) PULONG DisplayToId,
|
||||
__out_ecount_opt(Count) PPH_STRING *DisplayToText,
|
||||
__in ULONG Count,
|
||||
__out PULONG NumberOfColumns
|
||||
)
|
||||
{
|
||||
LVCOLUMN lvColumn;
|
||||
ULONG i;
|
||||
ULONG count;
|
||||
WCHAR buffer[128];
|
||||
|
||||
count = 0;
|
||||
lvColumn.mask = LVCF_ORDER | LVCF_TEXT;
|
||||
lvColumn.pszText = buffer;
|
||||
lvColumn.cchTextMax = sizeof(buffer) / sizeof(WCHAR);
|
||||
|
||||
for (i = 0; i < Count; i++)
|
||||
{
|
||||
if (ListView_GetColumn(ListViewHandle, i, &lvColumn))
|
||||
{
|
||||
ULONG displayIndex;
|
||||
|
||||
displayIndex = (ULONG)lvColumn.iOrder;
|
||||
assert(displayIndex < Count);
|
||||
DisplayToId[displayIndex] = i;
|
||||
|
||||
if (DisplayToText)
|
||||
DisplayToText[displayIndex] = PhaCreateString(buffer);
|
||||
|
||||
count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*NumberOfColumns = count;
|
||||
}
|
||||
|
||||
PPH_FULL_STRING PhGetListViewText(
|
||||
__in HWND ListViewHandle
|
||||
)
|
||||
{
|
||||
PPH_FULL_STRING string;
|
||||
ULONG displayToId[100];
|
||||
ULONG rows;
|
||||
ULONG columns;
|
||||
ULONG i;
|
||||
ULONG j;
|
||||
|
||||
PhapMapDisplayIndexListView(ListViewHandle, displayToId, NULL, 100, &columns);
|
||||
rows = ListView_GetItemCount(ListViewHandle);
|
||||
|
||||
string = PhCreateFullString2(0x100);
|
||||
|
||||
for (i = 0; i < rows; i++)
|
||||
{
|
||||
if (!(ListView_GetItemState(ListViewHandle, i, LVIS_SELECTED) & LVIS_SELECTED))
|
||||
continue;
|
||||
|
||||
for (j = 0; j < columns; j++)
|
||||
{
|
||||
WCHAR buffer[512];
|
||||
|
||||
buffer[0] = 0;
|
||||
ListView_GetItemText(ListViewHandle, i, j, buffer, sizeof(buffer) / sizeof(WCHAR));
|
||||
PhAppendFullString2(string, buffer);
|
||||
|
||||
PhAppendFullString2(string, L", ");
|
||||
}
|
||||
|
||||
// Remove the trailing comma and space.
|
||||
if (string->Length != 0)
|
||||
PhRemoveFullString(string, string->Length / 2 - 2, 2);
|
||||
|
||||
PhAppendFullString2(string, L"\r\n");
|
||||
}
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
PPH_LIST PhGetListViewLines(
|
||||
__in HWND ListViewHandle,
|
||||
__in ULONG Mode
|
||||
)
|
||||
{
|
||||
PH_AUTO_POOL autoPool;
|
||||
PPH_LIST lines;
|
||||
ULONG rows;
|
||||
ULONG columns;
|
||||
ULONG displayToId[100];
|
||||
PPH_STRING displayToText[100];
|
||||
PPH_STRING **table;
|
||||
ULONG i;
|
||||
ULONG j;
|
||||
|
||||
PhInitializeAutoPool(&autoPool);
|
||||
|
||||
rows = ListView_GetItemCount(ListViewHandle) + 1; // +1 for column headers
|
||||
|
||||
// Create the display index/text to ID map.
|
||||
PhapMapDisplayIndexListView(ListViewHandle, displayToId, displayToText, 100, &columns);
|
||||
|
||||
PhapCreateTextTable(&table, rows, columns);
|
||||
|
||||
// Populate the first row with the column headers.
|
||||
for (i = 0; i < columns; i++)
|
||||
table[0][i] = displayToText[i];
|
||||
|
||||
// Populate the other rows with text.
|
||||
for (i = 1; i < rows; i++)
|
||||
{
|
||||
for (j = 0; j < columns; j++)
|
||||
{
|
||||
WCHAR buffer[512];
|
||||
|
||||
// Important: use this to bypass extlv's hooking.
|
||||
// extlv only hooks LVM_GETITEM, not LVM_GETITEMTEXT.
|
||||
buffer[0] = 0;
|
||||
ListView_GetItemText(ListViewHandle, i - 1, j, buffer, sizeof(buffer) / sizeof(WCHAR));
|
||||
table[i][j] = PhaCreateString(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
lines = PhapFormatTextTable(table, rows, columns, Mode);
|
||||
|
||||
PhDeleteAutoPool(&autoPool);
|
||||
|
||||
return lines;
|
||||
}
|
||||
|
||||
VOID PhpEscapeStringForCsv(
|
||||
__inout PPH_STRING_BUILDER StringBuilder,
|
||||
__in PPH_STRING String
|
||||
@@ -496,7 +72,7 @@ VOID PhpEscapeStringForCsv(
|
||||
PhAppendStringBuilderEx(StringBuilder, runStart, runLength * sizeof(WCHAR));
|
||||
}
|
||||
|
||||
VOID PhapCreateTextTable(
|
||||
VOID PhaCreateTextTable(
|
||||
__out PPH_STRING ***Table,
|
||||
__in ULONG Rows,
|
||||
__in ULONG Columns
|
||||
@@ -517,7 +93,7 @@ VOID PhapCreateTextTable(
|
||||
*Table = table;
|
||||
}
|
||||
|
||||
PPH_LIST PhapFormatTextTable(
|
||||
PPH_LIST PhaFormatTextTable(
|
||||
__in PPH_STRING **Table,
|
||||
__in ULONG Rows,
|
||||
__in ULONG Columns,
|
||||
@@ -616,3 +192,297 @@ PPH_LIST PhapFormatTextTable(
|
||||
|
||||
return lines;
|
||||
}
|
||||
|
||||
VOID PhMapDisplayIndexTreeList(
|
||||
__in HWND TreeListHandle,
|
||||
__in ULONG MaximumNumberOfColumns,
|
||||
__out_ecount(MaximumNumberOfColumns) PULONG DisplayToId,
|
||||
__out_ecount_opt(MaximumNumberOfColumns) PWSTR *DisplayToText,
|
||||
__out PULONG NumberOfColumns
|
||||
)
|
||||
{
|
||||
PH_TREELIST_COLUMN column;
|
||||
ULONG i;
|
||||
ULONG count;
|
||||
|
||||
count = 0;
|
||||
|
||||
for (i = 0; i < MaximumNumberOfColumns; i++)
|
||||
{
|
||||
column.Id = i;
|
||||
|
||||
if (TreeList_GetColumn(TreeListHandle, &column))
|
||||
{
|
||||
if (column.Visible)
|
||||
{
|
||||
if (column.DisplayIndex < MaximumNumberOfColumns)
|
||||
{
|
||||
DisplayToId[column.DisplayIndex] = i;
|
||||
|
||||
if (DisplayToText)
|
||||
DisplayToText[column.DisplayIndex] = column.Text;
|
||||
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*NumberOfColumns = count;
|
||||
}
|
||||
|
||||
PPH_FULL_STRING PhGetTreeListText(
|
||||
__in HWND TreeListHandle,
|
||||
__in ULONG MaximumNumberOfColumns
|
||||
)
|
||||
{
|
||||
PPH_FULL_STRING string;
|
||||
PULONG displayToId;
|
||||
ULONG rows;
|
||||
ULONG columns;
|
||||
ULONG i;
|
||||
ULONG j;
|
||||
|
||||
displayToId = PhAllocate(MaximumNumberOfColumns * sizeof(ULONG));
|
||||
|
||||
PhMapDisplayIndexTreeList(TreeListHandle, MaximumNumberOfColumns, displayToId, NULL, &columns);
|
||||
rows = TreeList_GetVisibleNodeCount(TreeListHandle);
|
||||
|
||||
string = PhCreateFullString2(0x100);
|
||||
|
||||
for (i = 0; i < rows; i++)
|
||||
{
|
||||
PH_TL_GETNODETEXT getNodeText;
|
||||
|
||||
getNodeText.Node = TreeList_GetVisibleNode(TreeListHandle, i);
|
||||
assert(getNodeText.Node);
|
||||
|
||||
if (!getNodeText.Node->Selected)
|
||||
continue;
|
||||
|
||||
for (j = 0; j < columns; j++)
|
||||
{
|
||||
getNodeText.Id = displayToId[j];
|
||||
PhInitializeEmptyStringRef(&getNodeText.Text);
|
||||
TreeList_GetNodeText(TreeListHandle, &getNodeText);
|
||||
|
||||
PhAppendFullStringEx(string, getNodeText.Text.Buffer, getNodeText.Text.Length);
|
||||
PhAppendFullString2(string, L", ");
|
||||
}
|
||||
|
||||
// Remove the trailing comma and space.
|
||||
if (string->Length != 0)
|
||||
PhRemoveFullString(string, string->Length / 2 - 2, 2);
|
||||
|
||||
PhAppendFullString2(string, L"\r\n");
|
||||
}
|
||||
|
||||
PhFree(displayToId);
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
PPH_LIST PhGetGenericTreeListLines(
|
||||
__in HWND TreeListHandle,
|
||||
__in ULONG Mode
|
||||
)
|
||||
{
|
||||
PH_AUTO_POOL autoPool;
|
||||
PPH_LIST lines;
|
||||
ULONG rows;
|
||||
ULONG columns;
|
||||
ULONG numberOfNodes;
|
||||
ULONG maxId;
|
||||
PULONG displayToId;
|
||||
PWSTR *displayToText;
|
||||
PPH_STRING **table;
|
||||
ULONG i;
|
||||
ULONG j;
|
||||
|
||||
PhInitializeAutoPool(&autoPool);
|
||||
|
||||
numberOfNodes = TreeList_GetVisibleNodeCount(TreeListHandle);
|
||||
maxId = TreeList_GetMaxId(TreeListHandle) + 1;
|
||||
displayToId = PhAllocate(sizeof(ULONG) * maxId);
|
||||
displayToText = PhAllocate(sizeof(PWSTR) * maxId);
|
||||
|
||||
rows = numberOfNodes + 1;
|
||||
PhMapDisplayIndexTreeList(TreeListHandle, maxId, displayToId, displayToText, &columns);
|
||||
|
||||
PhaCreateTextTable(&table, rows, columns);
|
||||
|
||||
for (i = 0; i < columns; i++)
|
||||
table[0][i] = PhaCreateString(displayToText[i]);
|
||||
|
||||
for (i = 0; i < numberOfNodes; i++)
|
||||
{
|
||||
PPH_TREELIST_NODE node;
|
||||
|
||||
node = TreeList_GetVisibleNode(TreeListHandle, i);
|
||||
|
||||
if (node)
|
||||
{
|
||||
for (j = 0; j < columns; j++)
|
||||
{
|
||||
PH_TL_GETNODETEXT getNodeText;
|
||||
|
||||
getNodeText.Node = node;
|
||||
getNodeText.Id = displayToId[j];
|
||||
PhInitializeEmptyStringRef(&getNodeText.Text);
|
||||
TreeList_GetNodeText(TreeListHandle, &getNodeText);
|
||||
|
||||
table[i + 1][j] = PhaCreateStringEx(getNodeText.Text.Buffer, getNodeText.Text.Length);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (j = 0; j < columns; j++)
|
||||
{
|
||||
table[i + 1][j] = PHA_DEREFERENCE(PhReferenceEmptyString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PhFree(displayToText);
|
||||
PhFree(displayToId);
|
||||
|
||||
lines = PhaFormatTextTable(table, rows, columns, Mode);
|
||||
|
||||
PhDeleteAutoPool(&autoPool);
|
||||
|
||||
return lines;
|
||||
}
|
||||
|
||||
VOID PhaMapDisplayIndexListView(
|
||||
__in HWND ListViewHandle,
|
||||
__out_ecount(Count) PULONG DisplayToId,
|
||||
__out_ecount_opt(Count) PPH_STRING *DisplayToText,
|
||||
__in ULONG Count,
|
||||
__out PULONG NumberOfColumns
|
||||
)
|
||||
{
|
||||
LVCOLUMN lvColumn;
|
||||
ULONG i;
|
||||
ULONG count;
|
||||
WCHAR buffer[128];
|
||||
|
||||
count = 0;
|
||||
lvColumn.mask = LVCF_ORDER | LVCF_TEXT;
|
||||
lvColumn.pszText = buffer;
|
||||
lvColumn.cchTextMax = sizeof(buffer) / sizeof(WCHAR);
|
||||
|
||||
for (i = 0; i < Count; i++)
|
||||
{
|
||||
if (ListView_GetColumn(ListViewHandle, i, &lvColumn))
|
||||
{
|
||||
ULONG displayIndex;
|
||||
|
||||
displayIndex = (ULONG)lvColumn.iOrder;
|
||||
assert(displayIndex < Count);
|
||||
DisplayToId[displayIndex] = i;
|
||||
|
||||
if (DisplayToText)
|
||||
DisplayToText[displayIndex] = PhaCreateString(buffer);
|
||||
|
||||
count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*NumberOfColumns = count;
|
||||
}
|
||||
|
||||
PPH_FULL_STRING PhGetListViewText(
|
||||
__in HWND ListViewHandle
|
||||
)
|
||||
{
|
||||
PPH_FULL_STRING string;
|
||||
ULONG displayToId[100];
|
||||
ULONG rows;
|
||||
ULONG columns;
|
||||
ULONG i;
|
||||
ULONG j;
|
||||
|
||||
PhaMapDisplayIndexListView(ListViewHandle, displayToId, NULL, 100, &columns);
|
||||
rows = ListView_GetItemCount(ListViewHandle);
|
||||
|
||||
string = PhCreateFullString2(0x100);
|
||||
|
||||
for (i = 0; i < rows; i++)
|
||||
{
|
||||
if (!(ListView_GetItemState(ListViewHandle, i, LVIS_SELECTED) & LVIS_SELECTED))
|
||||
continue;
|
||||
|
||||
for (j = 0; j < columns; j++)
|
||||
{
|
||||
WCHAR buffer[512];
|
||||
|
||||
buffer[0] = 0;
|
||||
ListView_GetItemText(ListViewHandle, i, j, buffer, sizeof(buffer) / sizeof(WCHAR));
|
||||
PhAppendFullString2(string, buffer);
|
||||
|
||||
PhAppendFullString2(string, L", ");
|
||||
}
|
||||
|
||||
// Remove the trailing comma and space.
|
||||
if (string->Length != 0)
|
||||
PhRemoveFullString(string, string->Length / 2 - 2, 2);
|
||||
|
||||
PhAppendFullString2(string, L"\r\n");
|
||||
}
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
PPH_LIST PhGetListViewLines(
|
||||
__in HWND ListViewHandle,
|
||||
__in ULONG Mode
|
||||
)
|
||||
{
|
||||
PH_AUTO_POOL autoPool;
|
||||
PPH_LIST lines;
|
||||
ULONG rows;
|
||||
ULONG columns;
|
||||
ULONG displayToId[100];
|
||||
PPH_STRING displayToText[100];
|
||||
PPH_STRING **table;
|
||||
ULONG i;
|
||||
ULONG j;
|
||||
|
||||
PhInitializeAutoPool(&autoPool);
|
||||
|
||||
rows = ListView_GetItemCount(ListViewHandle) + 1; // +1 for column headers
|
||||
|
||||
// Create the display index/text to ID map.
|
||||
PhaMapDisplayIndexListView(ListViewHandle, displayToId, displayToText, 100, &columns);
|
||||
|
||||
PhaCreateTextTable(&table, rows, columns);
|
||||
|
||||
// Populate the first row with the column headers.
|
||||
for (i = 0; i < columns; i++)
|
||||
table[0][i] = displayToText[i];
|
||||
|
||||
// Populate the other rows with text.
|
||||
for (i = 1; i < rows; i++)
|
||||
{
|
||||
for (j = 0; j < columns; j++)
|
||||
{
|
||||
WCHAR buffer[512];
|
||||
|
||||
// Important: use this to bypass extlv's hooking.
|
||||
// extlv only hooks LVM_GETITEM, not LVM_GETITEMTEXT.
|
||||
buffer[0] = 0;
|
||||
ListView_GetItemText(ListViewHandle, i - 1, j, buffer, sizeof(buffer) / sizeof(WCHAR));
|
||||
table[i][j] = PhaCreateString(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
lines = PhaFormatTextTable(table, rows, columns, Mode);
|
||||
|
||||
PhDeleteAutoPool(&autoPool);
|
||||
|
||||
return lines;
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
#ifndef _PH_CPYSAVE_H
|
||||
#define _PH_CPYSAVE_H
|
||||
|
||||
#define PH_EXPORT_MODE_TABS 0
|
||||
#define PH_EXPORT_MODE_SPACES 1
|
||||
#define PH_EXPORT_MODE_CSV 2
|
||||
|
||||
VOID PhaCreateTextTable(
|
||||
__out PPH_STRING ***Table,
|
||||
__in ULONG Rows,
|
||||
__in ULONG Columns
|
||||
);
|
||||
|
||||
PPH_LIST PhaFormatTextTable(
|
||||
__in PPH_STRING **Table,
|
||||
__in ULONG Rows,
|
||||
__in ULONG Columns,
|
||||
__in ULONG Mode
|
||||
);
|
||||
|
||||
VOID PhMapDisplayIndexTreeList(
|
||||
__in HWND TreeListHandle,
|
||||
__in ULONG MaximumNumberOfColumns,
|
||||
__out_ecount(MaximumNumberOfColumns) PULONG DisplayToId,
|
||||
__out_ecount_opt(MaximumNumberOfColumns) PWSTR *DisplayToText,
|
||||
__out PULONG NumberOfColumns
|
||||
);
|
||||
|
||||
PHLIBAPI
|
||||
PPH_FULL_STRING PhGetTreeListText(
|
||||
__in HWND TreeListHandle,
|
||||
__in ULONG MaximumNumberOfColumns
|
||||
);
|
||||
|
||||
PPH_LIST PhGetGenericTreeListLines(
|
||||
__in HWND TreeListHandle,
|
||||
__in ULONG Mode
|
||||
);
|
||||
|
||||
VOID PhaMapDisplayIndexListView(
|
||||
__in HWND ListViewHandle,
|
||||
__out_ecount(Count) PULONG DisplayToId,
|
||||
__out_ecount_opt(Count) PPH_STRING *DisplayToText,
|
||||
__in ULONG Count,
|
||||
__out PULONG NumberOfColumns
|
||||
);
|
||||
|
||||
PPH_FULL_STRING PhGetListViewText(
|
||||
__in HWND ListViewHandle
|
||||
);
|
||||
|
||||
PPH_LIST PhGetListViewLines(
|
||||
__in HWND ListViewHandle,
|
||||
__in ULONG Mode
|
||||
);
|
||||
|
||||
#endif
|
||||
@@ -359,6 +359,14 @@ HWND PhCreateTreeListControlEx(
|
||||
__in ULONG Style
|
||||
);
|
||||
|
||||
__callback BOOLEAN NTAPI PhTreeListNullCallback(
|
||||
__in HWND hwnd,
|
||||
__in PH_TREELIST_MESSAGE Message,
|
||||
__in_opt PVOID Parameter1,
|
||||
__in_opt PVOID Parameter2,
|
||||
__in_opt PVOID Context
|
||||
);
|
||||
|
||||
PHLIBAPI
|
||||
VOID PhInitializeTreeListNode(
|
||||
__in PPH_TREELIST_NODE Node
|
||||
@@ -410,12 +418,4 @@ PPH_STRING PhSaveTreeListColumnSettings(
|
||||
__in HWND TreeListHandle
|
||||
);
|
||||
|
||||
__callback BOOLEAN NTAPI PhTreeListNullCallback(
|
||||
__in HWND hwnd,
|
||||
__in PH_TREELIST_MESSAGE Message,
|
||||
__in_opt PVOID Parameter1,
|
||||
__in_opt PVOID Parameter2,
|
||||
__in_opt PVOID Context
|
||||
);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -166,6 +166,7 @@
|
||||
<ClCompile Include="circbuf.c" />
|
||||
<ClCompile Include="collect.c" />
|
||||
<ClCompile Include="colorbox.c" />
|
||||
<ClCompile Include="cpysave.c" />
|
||||
<ClCompile Include="data.c" />
|
||||
<ClCompile Include="dspick.c" />
|
||||
<ClCompile Include="emenu.c" />
|
||||
@@ -224,6 +225,7 @@
|
||||
<ClCompile Include="workqueue.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="include\cpysave.h" />
|
||||
<ClInclude Include="include\kphapi.h" />
|
||||
<ClInclude Include="include\ntpfapi.h" />
|
||||
<ClInclude Include="include\ntzwapi.h" />
|
||||
|
||||
@@ -201,6 +201,9 @@
|
||||
<ClCompile Include="workqueue.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="cpysave.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="include\phsync.h">
|
||||
@@ -425,6 +428,9 @@
|
||||
<ClInclude Include="include\ntpfapi.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\cpysave.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="pcre\pcre_printint.src" />
|
||||
|
||||
+11
-11
@@ -2277,6 +2277,17 @@ static VOID PhpReloadThemeData(
|
||||
}
|
||||
}
|
||||
|
||||
__callback BOOLEAN NTAPI PhTreeListNullCallback(
|
||||
__in HWND hwnd,
|
||||
__in PH_TREELIST_MESSAGE Message,
|
||||
__in_opt PVOID Parameter1,
|
||||
__in_opt PVOID Parameter2,
|
||||
__in_opt PVOID Context
|
||||
)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
VOID PhInitializeTreeListNode(
|
||||
__in PPH_TREELIST_NODE Node
|
||||
)
|
||||
@@ -2559,14 +2570,3 @@ PPH_STRING PhSaveTreeListColumnSettings(
|
||||
|
||||
return PhFinalStringBuilderString(&stringBuilder);
|
||||
}
|
||||
|
||||
__callback BOOLEAN NTAPI PhTreeListNullCallback(
|
||||
__in HWND hwnd,
|
||||
__in PH_TREELIST_MESSAGE Message,
|
||||
__in_opt PVOID Parameter1,
|
||||
__in_opt PVOID Parameter2,
|
||||
__in_opt PVOID Context
|
||||
)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -9,8 +9,23 @@
|
||||
extern PPH_STRING PvFileName;
|
||||
#endif
|
||||
|
||||
// peprp
|
||||
|
||||
VOID PvPeProperties();
|
||||
|
||||
// libprp
|
||||
|
||||
VOID PvLibProperties();
|
||||
|
||||
// misc
|
||||
|
||||
VOID PvCopyListView(
|
||||
__in HWND ListViewHandle
|
||||
);
|
||||
|
||||
VOID PvHandleListViewNotifyForCopy(
|
||||
__in LPARAM lParam,
|
||||
__in HWND ListViewHandle
|
||||
);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -164,6 +164,11 @@ INT_PTR CALLBACK PvpLibExportsDlgProc(
|
||||
ExtendedListView_SortItems(lvHandle);
|
||||
}
|
||||
break;
|
||||
case WM_NOTIFY:
|
||||
{
|
||||
PvHandleListViewNotifyForCopy(lParam, GetDlgItem(hwndDlg, IDC_LIST));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Process Hacker -
|
||||
* PE viewer
|
||||
*
|
||||
* Copyright (C) 2011 wj32
|
||||
*
|
||||
* This file is part of Process Hacker.
|
||||
*
|
||||
* Process Hacker is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Process Hacker is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <peview.h>
|
||||
#include <cpysave.h>
|
||||
|
||||
// Copied from appsup.c
|
||||
|
||||
VOID PvCopyListView(
|
||||
__in HWND ListViewHandle
|
||||
)
|
||||
{
|
||||
PPH_FULL_STRING text;
|
||||
|
||||
text = PhGetListViewText(ListViewHandle);
|
||||
PhSetClipboardStringEx(ListViewHandle, text->Buffer, text->Length);
|
||||
PhDereferenceObject(text);
|
||||
}
|
||||
|
||||
VOID PvHandleListViewNotifyForCopy(
|
||||
__in LPARAM lParam,
|
||||
__in HWND ListViewHandle
|
||||
)
|
||||
{
|
||||
if (((LPNMHDR)lParam)->hwndFrom == ListViewHandle)
|
||||
{
|
||||
LPNMLVKEYDOWN keyDown = (LPNMLVKEYDOWN)lParam;
|
||||
|
||||
switch (keyDown->wVKey)
|
||||
{
|
||||
case 'C':
|
||||
if (GetKeyState(VK_CONTROL) < 0)
|
||||
PvCopyListView(ListViewHandle);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,7 @@
|
||||
*/
|
||||
|
||||
#include <peview.h>
|
||||
#include <cpysave.h>
|
||||
|
||||
#define PVM_CHECKSUM_DONE (WM_APP + 1)
|
||||
|
||||
@@ -353,6 +354,11 @@ INT_PTR CALLBACK PvpPeGeneralDlgProc(
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WM_NOTIFY:
|
||||
{
|
||||
PvHandleListViewNotifyForCopy(lParam, GetDlgItem(hwndDlg, IDC_LIST));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
@@ -428,6 +434,11 @@ INT_PTR CALLBACK PvpPeImportsDlgProc(
|
||||
ExtendedListView_SortItems(lvHandle);
|
||||
}
|
||||
break;
|
||||
case WM_NOTIFY:
|
||||
{
|
||||
PvHandleListViewNotifyForCopy(lParam, GetDlgItem(hwndDlg, IDC_LIST));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
@@ -504,6 +515,11 @@ INT_PTR CALLBACK PvpPeExportsDlgProc(
|
||||
ExtendedListView_SortItems(lvHandle);
|
||||
}
|
||||
break;
|
||||
case WM_NOTIFY:
|
||||
{
|
||||
PvHandleListViewNotifyForCopy(lParam, GetDlgItem(hwndDlg, IDC_LIST));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
|
||||
@@ -182,6 +182,7 @@
|
||||
<ItemGroup>
|
||||
<ClCompile Include="libprp.c" />
|
||||
<ClCompile Include="main.c" />
|
||||
<ClCompile Include="misc.c" />
|
||||
<ClCompile Include="peprp.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -24,6 +24,9 @@
|
||||
<ClCompile Include="peprp.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="misc.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="include\peview.h">
|
||||
|
||||
Reference in New Issue
Block a user