在Program.cs中我添加了一个类:
public static class Menus
{
public static string MenuShare1 = "FaceBook";
public static string MenyShare2 = "Tapuz";
}
然后我又添加了一个上下文菜单字符串变量:
const string MenuText2 = "Share >";
我想要做的是当我在今天的目录中右键单击鼠标时,它现在显示我"复制到灰度"和"调整所有图像的大小"我希望它也显示上下文菜单"分享>"当我点击或将鼠标移到"分享>"它将从菜单中打开子上下文菜单:
的FaceBook Tapuz
如果我点击FaceBook或Tapuz那么它会做点什么。
在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
{
public static class Menus
{
public static string MenuShare1 = "FaceBook";
public static string MenyShare2 = "Tapuz";
}
// 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";
const string MenuText2 = "Share >";
[STAThread]
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 == "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(fileName,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;
}
}
}
}
和FileShellExtension.cs
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);
}
}
}
更新
这是我现在尝试的。 在Main方法的Program.cs中,我补充说:
else if (action == "Share")
{
// create full path to registry location under the key you created
string regSubPath = string.Format(@"{0}\shell\{1}\Share", FileType, KeyName2);
// add context menu to the registry
using (Microsoft.Win32.RegistryKey key = Microsoft.Win32.Registry.ClassesRoot.CreateSubKey(regSubPath))
{
key.SetValue(null, "Tapuz");
}
}
但是当我点击&#34;分享媒体&#34;它没有显示子菜单 在第二个子菜单打开后将鼠标移到上下文菜单上而不点击它时,最好像在文件浏览器中一样。
例如:发送至 当你将鼠标移到它上面时,有一个发送到右侧带有黑色小箭头的菜单,它会打开一个子上下文菜单。
答案 0 :(得分:1)
查看this question和official documentation(以及您的代码),我认为您只需要在注册表中的“共享&#39;”下的路径中创建菜单项。菜单项。
换句话说,如果您打开regedit并浏览到相关分支(HKEY_CLASSES_ROOT.fileType \ Shell \ Share)并添加Tapuz,它会将子菜单添加到Windows资源管理器。执行此操作的命令(可能):
using (RegistryKey key = Registry.ClassesRoot.CreateSubKey(regPath))
{
key.SetValue(null, "Tapuz");
}
我假设您谈到的条件(如果action == share)用于设置回调。换句话说,如果你点击共享会运行什么。由于分享是子菜单的标题,我想说这不是必需的。
=============================================== ========================= 只是为了澄清。
在任何情况下,请始终根据注册表中的内容检查程序输出,以及它应该反映的位置,并与已知的内容进行比较,例如打开...