我要做的是添加两个上下文菜单,"复制到灰度"和"列出所有图像"。
我传递一个参数" List" /" Copy"区分它们。
string menuCommand = string.Format("\"{0}\"{1}\" \"%L\" CopyGrayscaleImage", " List", Application.ExecutablePath);
但这是错误的。
menuCommand行应该是什么样子以及如何在Main方法中处理它?</ p>
这是类FileShellExtensions
using System;
using System.Diagnostics;
using Microsoft.Win32;
namespace SimpleContextMenu
{
/// <summary>
/// Register and unregister simple shell context menus.
/// </summary>
static class FileShellExtension
{
/// <summary>
/// Register a simple shell context menu.
/// </summary>
/// <param name="fileType">The file type to register.</param>
/// <param name="shellKeyName">Name that appears in the registry.</param>
/// <param name="menuText">Text that appears in the context menu.</param>
/// <param name="menuCommand">Command line that is executed.</param>
public static void Register(
string fileType, string shellKeyName,
string menuText, string menuCommand)
{
Debug.Assert(!string.IsNullOrEmpty(fileType) &&
!string.IsNullOrEmpty(shellKeyName) &&
!string.IsNullOrEmpty(menuText) &&
!string.IsNullOrEmpty(menuCommand));
// create full path to registry location
string regPath = string.Format(@"{0}\shell\{1}", fileType, shellKeyName);
// add context menu to the registry
using (RegistryKey key = Registry.ClassesRoot.CreateSubKey(regPath))
{
key.SetValue(null, menuText);
}
// add command that is invoked to the registry
using (RegistryKey key = Registry.ClassesRoot.CreateSubKey(
string.Format(@"{0}\command", regPath)))
{
key.SetValue(null, menuCommand);
}
}
/// <summary>
/// Unregister a simple shell context menu.
/// </summary>
/// <param name="fileType">The file type to unregister.</param>
/// <param name="shellKeyName">Name that was registered in the registry.</param>
public static void Unregister(string fileType, string shellKeyName)
{
Debug.Assert(!string.IsNullOrEmpty(fileType) &&
!string.IsNullOrEmpty(shellKeyName));
// full path to the registry location
string regPath = string.Format(@"{0}\shell\{1}", fileType, shellKeyName);
// remove context menu from the registry
Registry.ClassesRoot.DeleteSubKeyTree(regPath);
}
}
}
这是Progrsm.cs
using System;
using System.Windows.Forms;
using System.IO;
using System.Drawing;
using System.Drawing.Imaging;
[assembly: CLSCompliant(true)]
namespace SimpleContextMenu
{
static class Program
{
// file type to register
const string FileType = "jpegfile";
// context menu name in the registry
const string KeyName = "Simple Context Menu";
const string KeyName1 = "Simple Context Menu1";
// context menu text
const string MenuText = "Copy to Grayscale";
const string MenuText1 = "List all images";
[STAThread]
static void Main(string[] args)
{
// process register or unregister commands
if (!ProcessCommand(args))
{
// invoked from shell, process the selected file
CopyGrayscaleImage(args[0]);
}
}
/// <summary>
/// Process command line actions (register or unregister).
/// </summary>
/// <param name="args">Command line arguments.</param>
/// <returns>True if processed an action in the command line.</returns>
static bool ProcessCommand(string[] args)
{
// register
if (args.Length == 0 || string.Compare(args[0], "-register", true) == 0)
{
// full path to self, %L is placeholder for selected file
//string menuCommand = string.Format(
//"\"{0}\" \"%L\"", Application.ExecutablePath);
string menuCommand = string.Format("\"{0}\"{1}\" \"%L\" CopyGrayscaleImage", " List", Application.ExecutablePath);
// register the context menu
FileShellExtension.Register(Program.FileType,
Program.KeyName, Program.MenuText,
menuCommand);
FileShellExtension.Register(Program.FileType,
Program.KeyName1, Program.MenuText1,
menuCommand);
MessageBox.Show(string.Format(
"The {0} shell extension was registered.",
Program.KeyName), Program.KeyName);
return true;
}
// unregister
if (string.Compare(args[0], "-unregister", true) == 0)
{
// unregister the context menu
FileShellExtension.Unregister(Program.FileType, Program.KeyName);
MessageBox.Show(string.Format(
"The {0} shell extension was unregistered.",
Program.KeyName), Program.KeyName);
return true;
}
// command line did not contain an action
return false;
}
/// <summary>
/// Make a grayscale copy of the image.
/// </summary>
/// <param name="filePath">Full path to the image to copy.</param>
static void CopyGrayscaleImage(string filePath)
{
try
{
// full path to the grayscale copy
string grayFilePath = Path.Combine(
Path.GetDirectoryName(filePath),
string.Format("{0} (grayscale){1}",
Path.GetFileNameWithoutExtension(filePath),
Path.GetExtension(filePath)));
// using calls Dispose on the objects, important
// so the file is not locked when the app terminates
using (Image image = new Bitmap(filePath))
using (Bitmap grayImage = new Bitmap(image.Width, image.Height))
using (Graphics g = Graphics.FromImage(grayImage))
{
// setup grayscale matrix
ImageAttributes attr = new ImageAttributes();
attr.SetColorMatrix(new ColorMatrix(new float[][]{
new float[]{0.3086F,0.3086F,0.3086F,0,0},
new float[]{0.6094F,0.6094F,0.6094F,0,0},
new float[]{0.082F,0.082F,0.082F,0,0},
new float[]{0,0,0,1,0,0},
new float[]{0,0,0,0,1,0},
new float[]{0,0,0,0,0,1}}));
// create the grayscale image
g.DrawImage(image, new Rectangle(0, 0, image.Width, image.Height),
0, 0, image.Width, image.Height, GraphicsUnit.Pixel, attr);
// save to the file system
grayImage.Save(grayFilePath, ImageFormat.Jpeg);
// success
MessageBox.Show(string.Format("Copied grayscale image {0}", grayFilePath), Program.KeyName);
}
}
catch (Exception ex)
{
MessageBox.Show(string.Format("An error occurred: {0}", ex.Message), Program.KeyName);
return;
}
}
}
}
更新
这是Program.cs现在
using System;
using System.Windows.Forms;
using System.IO;
using System.Drawing;
using System.Drawing.Imaging;
[assembly: CLSCompliant(true)]
namespace SimpleContextMenu
{
static class Program
{
// file type to register
const string FileType = "bitmapfile";//"jpegfile";
// context menu name in the registry
const string KeyName = "Simple Context Menu";
const string KeyName1 = "Simple Context Menu1";
// context menu text
const string MenuText = "Copy to Grayscale";
const string MenuText1 = "Resize all images";
[STAThread]
static void Main(string[] args)
{
System.Threading.Thread.Sleep(30000);
// process register or unregister commands
if (!ProcessCommand(args))
{
string action = args[0];
MessageBox.Show(action);
string fileName = args[1];
if (action == "Copy")
{
// invoked from shell, process the selected file
CopyGrayscaleImage(fileName);
}
else if (action == "Resize")
{
string FilePath = Path.Combine(
Path.GetDirectoryName(fileName),
string.Format("{0} (resized){1}",
Path.GetFileNameWithoutExtension(fileName),
Path.GetExtension(fileName)));
MessageBox.Show(FilePath);
Bitmap bmp1 = new Bitmap(ResizeImages(FilePath,100,100));
bmp1.Save(FilePath);
bmp1.Dispose();
}
}
}
/// <summary>
/// Process command line actions (register or unregister).
/// </summary>
/// <param name="args">Command line arguments.</param>
/// <returns>True if processed an action in the command line.</returns>
static bool ProcessCommand(string[] args)
{
// register
if (args.Length == 0 || string.Compare(args[0], "-register", true) == 0)
{
// full path to self, %L is placeholder for selected file
string menuCommand = string.Format("\"{0}\" Copy \"%L\"", Application.ExecutablePath);
// register the context menu
FileShellExtension.Register(Program.FileType,
Program.KeyName, Program.MenuText,
menuCommand);
string menuCommand1 = string.Format("\"{0}\" Resize \"%L\"", Application.ExecutablePath);
FileShellExtension.Register(Program.FileType,
Program.KeyName1, Program.MenuText1,
menuCommand1);
MessageBox.Show(string.Format(
"The {0} shell extension was registered.",
Program.KeyName), Program.KeyName);
return true;
}
// unregister
if (string.Compare(args[0], "-unregister", true) == 0)
{
// unregister the context menu
FileShellExtension.Unregister(Program.FileType, Program.KeyName);
MessageBox.Show(string.Format(
"The {0} shell extension was unregistered.",
Program.KeyName), Program.KeyName);
return true;
}
// command line did not contain an action
return false;
}
/// <summary>
/// Make a grayscale copy of the image.
/// </summary>
/// <param name="filePath">Full path to the image to copy.</param>
static void CopyGrayscaleImage(string filePath)
{
try
{
// full path to the grayscale copy
string grayFilePath = Path.Combine(
Path.GetDirectoryName(filePath),
string.Format("{0} (grayscale){1}",
Path.GetFileNameWithoutExtension(filePath),
Path.GetExtension(filePath)));
// using calls Dispose on the objects, important
// so the file is not locked when the app terminates
using (Image image = new Bitmap(filePath))
using (Bitmap grayImage = new Bitmap(image.Width, image.Height))
using (Graphics g = Graphics.FromImage(grayImage))
{
// setup grayscale matrix
ImageAttributes attr = new ImageAttributes();
attr.SetColorMatrix(new ColorMatrix(new float[][]{
new float[]{0.3086F,0.3086F,0.3086F,0,0},
new float[]{0.6094F,0.6094F,0.6094F,0,0},
new float[]{0.082F,0.082F,0.082F,0,0},
new float[]{0,0,0,1,0,0},
new float[]{0,0,0,0,1,0},
new float[]{0,0,0,0,0,1}}));
// create the grayscale image
g.DrawImage(image, new Rectangle(0, 0, image.Width, image.Height),
0, 0, image.Width, image.Height, GraphicsUnit.Pixel, attr);
// save to the file system
grayImage.Save(grayFilePath, ImageFormat.Jpeg);
// success
MessageBox.Show(string.Format("Copied grayscale image {0}", grayFilePath), Program.KeyName);
}
}
catch (Exception ex)
{
MessageBox.Show(string.Format("An error occurred: {0}", ex.Message), Program.KeyName);
return;
}
}
private static Bitmap ResizeImages(String filename, int maxWidth, int maxHeight)
{
using (Image originalImage = Image.FromFile(filename))
{
//Caluate new Size
int newWidth = originalImage.Width;
int newHeight = originalImage.Height;
double aspectRatio = (double)originalImage.Width / (double)originalImage.Height;
if (aspectRatio <= 1 && originalImage.Width > maxWidth)
{
newWidth = maxWidth;
newHeight = (int)Math.Round(newWidth / aspectRatio);
}
else if (aspectRatio > 1 && originalImage.Height > maxHeight)
{
newHeight = maxHeight;
newWidth = (int)Math.Round(newHeight * aspectRatio);
}
if (newWidth >= 0 && newHeight >= 0)
{
Bitmap newImage = new Bitmap(newWidth, newHeight);
using (Graphics g = Graphics.FromImage(newImage))
{
//--Quality Settings Adjust to fit your application
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBilinear;
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
g.DrawImage(originalImage, 0, 0, newImage.Width, newImage.Height);
return newImage;
}
}
return null;
}
}
}
}
出于某种原因,Resize部分并不具体。 我无法调试它,但它应该将调整大小的位图图像文件保存在我的硬盘上,但事实并非如此。无法弄清楚。
答案 0 :(得分:0)
查看menuCommand
字符串,第一部分应该是程序的路径:Application.ExecutablePath
,第二部分可以是您指定的操作(“复制”或“列表”),以及第三部分可以是所选项目的完整路径,由“%L”占位符表示。
所以正确的方法是
string menuCommand = string.Format("\"{0}\" Copy \"%L\"", Application.ExecutablePath);
// register the context menu
FileShellExtension.Register(Program.FileType,
Program.KeyName, Program.MenuText,
menuCommand);
string menuCommand1 = string.Format("\"{0}\" List \"%L\"", Application.ExecutablePath);
// register the context menu 1
FileShellExtension.Register(Program.FileType,
Program.KeyName1, Program.MenuText1,
menuCommand1);
主要方法
static void Main(string[] args)
{
// process register or unregister commands
if (!ProcessCommand(args))
{
string action = args[0];
MessageBox.Show(action);
string fileName = args[1];
if (action == "Copy")
{
// invoked from shell, process the selected file
CopyGrayscaleImage(fileName);
}
else if (action == "List")
{
ListImage(fileName);
}
}
}