mirror of
https://git.femboyfinancial.jp/james/lipsync.git
synced 2025-11-20 21:23:43 -08:00
git-svn-id: http://svn.sourceforge.jp/svnroot/lipsync@4 b1f601f4-4f45-0410-8980-aecacb008692
This commit is contained in:
45
trunk/LipSync/Common/AviutlPlugin.cs
Normal file
45
trunk/LipSync/Common/AviutlPlugin.cs
Normal file
@@ -0,0 +1,45 @@
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Boare.Lib.AviutlPlugin{
|
||||
|
||||
/*class aviutl {
|
||||
|
||||
[DllImport( "Invoke", EntryPoint="GetFilterTable")]
|
||||
public extern static FILTER_DLL GetFilterTable();
|
||||
|
||||
}
|
||||
|
||||
|
||||
struct FILTER_DLL {
|
||||
int flag;
|
||||
int x,y;
|
||||
TCHAR *name;
|
||||
int track_n;
|
||||
TCHAR **track_name;
|
||||
int* track_default;
|
||||
int* track_s;
|
||||
int* track_e;
|
||||
int check_n;
|
||||
TCHAR **check_name;
|
||||
int* check_default;
|
||||
BOOL (*func_proc)( FILTER *fp,FILTER_PROC_INFO *fpip );
|
||||
BOOL (*func_init)( FILTER *fp );
|
||||
BOOL (*func_exit)( FILTER *fp );
|
||||
BOOL (*func_update)( FILTER *fp,int status );
|
||||
BOOL (*func_WndProc)( HWND hwnd,UINT message,WPARAM wparam,LPARAM lparam,void *editp,FILTER *fp );
|
||||
int* track;
|
||||
int* check;
|
||||
void* ex_data_ptr;
|
||||
int ex_data_size;
|
||||
TCHAR *information;
|
||||
BOOL (*func_save_start)( FILTER *fp,int s,int e,void *editp );
|
||||
BOOL (*func_save_end)( FILTER *fp,void *editp );
|
||||
EXFUNC *exfunc;
|
||||
HWND hwnd;
|
||||
HINSTANCE dll_hinst;
|
||||
void* ex_data_def;
|
||||
BOOL (*func_is_saveframe)( FILTER *fp,void *editp,int saveno,int frame,int fps,int edit_flag,int inter );
|
||||
int[] reserve = new int[6];
|
||||
}*/
|
||||
|
||||
}
|
||||
264
trunk/LipSync/Common/Common.cs
Normal file
264
trunk/LipSync/Common/Common.cs
Normal file
@@ -0,0 +1,264 @@
|
||||
/*
|
||||
* Common.cs
|
||||
* Copyright (c) 2007-2009 kbinani
|
||||
*
|
||||
* This file is part of LipSync.
|
||||
*
|
||||
* LipSync is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the BSD License.
|
||||
*
|
||||
* LipSync 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.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace LipSync {
|
||||
|
||||
/// <summary>
|
||||
/// LipSync共用の関数
|
||||
/// </summary>
|
||||
public class Common {
|
||||
private static string m_log_file = "";
|
||||
private static StreamWriter m_sw = null;
|
||||
private static SaveFileDialog s_dialog = null;
|
||||
public static Color CURVE_X = Color.Black;
|
||||
public static Color CURVE_Y = Color.White;
|
||||
public static Color CURVE_SCALE = Color.Orange;
|
||||
public static Color CURVE_ALPHA = Color.Red;
|
||||
public static Color CURVE_ROTATE = Color.Navy;
|
||||
|
||||
/// <summary>
|
||||
/// ファイルダイアログのFilterに指定しようとしている文字列がエラーを起こさないかどうかを確かめます
|
||||
/// </summary>
|
||||
/// <param name="filter"></param>
|
||||
/// <returns></returns>
|
||||
public static bool CheckFilterValidity( string filter ) {
|
||||
if ( s_dialog == null ) {
|
||||
s_dialog = new SaveFileDialog();
|
||||
}
|
||||
try {
|
||||
s_dialog.Filter = filter;
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static void DebugWriteLine( string s ) {
|
||||
#if DEBUG
|
||||
#if MONO
|
||||
Console.WriteLine( s );
|
||||
System.Diagnostics.Trace.WriteLine( s );
|
||||
System.Diagnostics.Debug.WriteLine( s );
|
||||
#else
|
||||
//System.Diagnostics.Debug.WriteLine( s );
|
||||
Console.WriteLine( s );
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
public static Image GetThumbnailImage( Image image, int width, int height ) {
|
||||
Bitmap res = new Bitmap( width, height, PixelFormat.Format32bppArgb );
|
||||
if ( image == null ) {
|
||||
return res;
|
||||
}
|
||||
int w = image.Width;
|
||||
int h = image.Height;
|
||||
float ASPECTO = (float)width / (float)height;
|
||||
float aspecto = (float)w / (float)h;
|
||||
float order = 1f; //拡大率
|
||||
int top = 0; //描画位置y座標
|
||||
int left = 0; //描画位置x座標
|
||||
if ( ASPECTO > aspecto ) {
|
||||
// サムネイルのほうが横長
|
||||
order = (float)height / (float)h;
|
||||
left = (int)(width - order * w) / 2;
|
||||
} else {
|
||||
// サムネイルのほうが縦長
|
||||
order = (float)width / (float)w;
|
||||
top = (int)(height - order * h) / 2;
|
||||
}
|
||||
using ( Graphics g = Graphics.FromImage( res ) ) {
|
||||
g.Clear( Color.Transparent );
|
||||
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
|
||||
g.DrawImage( image, left, top, w * order, h * order );
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 2つの整数の最大公約数を返します。
|
||||
/// </summary>
|
||||
/// <param name="m"></param>
|
||||
/// <param name="n"></param>
|
||||
/// <returns></returns>
|
||||
public static long GetGCD( long m, long n ) {
|
||||
if ( n > m ) {
|
||||
long a = n;
|
||||
n = m;
|
||||
m = a;
|
||||
}
|
||||
while ( true ) {
|
||||
if ( n == 0 ) {
|
||||
return m;
|
||||
}
|
||||
long quotient = m / n;
|
||||
long odd = m - n * quotient;
|
||||
if ( odd == 0 ) {
|
||||
return n;
|
||||
}
|
||||
m = n;
|
||||
n = odd;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static Point PointFromPointF( PointF point_f ) {
|
||||
return new Point( (int)point_f.X, (int)point_f.Y );
|
||||
}
|
||||
|
||||
|
||||
public static Size SizeFromSizeF( SizeF size_f ) {
|
||||
return new Size( (int)size_f.Width, (int)size_f.Height );
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 画像から不透明領域を検出する。
|
||||
/// </summary>
|
||||
/// <param name="bmp"></param>
|
||||
/// <returns></returns>
|
||||
public static Rectangle GetNonTransparentRegion( Bitmap bmp ) {
|
||||
if ( bmp.PixelFormat != PixelFormat.Format32bppArgb ) {
|
||||
return new Rectangle();
|
||||
}
|
||||
BitmapData bmpdat = bmp.LockBits(
|
||||
new Rectangle( 0, 0, bmp.Width, bmp.Height ),
|
||||
ImageLockMode.ReadOnly,
|
||||
PixelFormat.Format32bppArgb
|
||||
);
|
||||
|
||||
int stride = bmpdat.Stride;
|
||||
|
||||
int ymax = 0;
|
||||
int ymin = (bmp.Height - 1) * stride;
|
||||
int xmax = 0;
|
||||
int xmin = (bmp.Width - 1) * 4;
|
||||
const byte ZERO = 0;
|
||||
unsafe {
|
||||
byte* dat = (byte*)(void*)bmpdat.Scan0;
|
||||
int xend = bmp.Width * 4;
|
||||
int yend;
|
||||
for ( int x = 0; x < xend; x += 4 ) {
|
||||
// yminを決める
|
||||
yend = ymin;//ymin* stride;
|
||||
for ( int y = 0; y <= yend; y += stride ) {
|
||||
if ( dat[x + y + 3] != ZERO ) {
|
||||
//ymin = Math.Min( ymin, y / stride );
|
||||
ymin = Math.Min( ymin, y );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// ymaxを決める
|
||||
yend = ymax;// ymax * stride;
|
||||
for ( int y = (bmp.Height - 1) * stride; y >= yend; y -= stride ) {
|
||||
if ( dat[x + y + 3] != ZERO ) {
|
||||
//ymax = Math.Max( ymax, y / stride );
|
||||
ymax = Math.Max( ymax, y );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
yend = ymax;// ymax * stride;
|
||||
for ( int y = ymin; y <= yend; y += stride ) {
|
||||
// xminを決める
|
||||
for ( int x = 0; x < xmin; x += 4 ) {
|
||||
if ( dat[x + y + 3] != ZERO ) {
|
||||
//xmin = Math.Min( xmin, x / 4 );
|
||||
xmin = Math.Min( xmin, x );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// xmaxを決める
|
||||
for ( int x = (bmp.Width - 1) * 4; x >= xmax; x -= 4 ) {
|
||||
if ( dat[x + y + 3] != ZERO ) {
|
||||
//xmax = Math.Max( xmax, x / 4 );
|
||||
xmax = Math.Max( xmax, x );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( xmax <= xmin || ymax <= ymin ) {
|
||||
xmin = 0;
|
||||
xmax = bmp.Width - 1;
|
||||
ymin = 0;
|
||||
ymax = bmp.Height - 1;
|
||||
} else {
|
||||
xmin = xmin / 4;
|
||||
xmax = xmax / 4;
|
||||
ymin = ymin / stride;
|
||||
ymax = ymax / stride;
|
||||
}
|
||||
}
|
||||
bmp.UnlockBits( bmpdat );
|
||||
return new Rectangle( xmin, ymin, xmax - xmin + 1, ymax - ymin + 1 );
|
||||
}
|
||||
|
||||
public static void LogPush( Exception ex ) {
|
||||
LogPush( ex.Source + Environment.NewLine + ex.Message + Environment.NewLine + ex.StackTrace );
|
||||
}
|
||||
public static void LogPush( string procedure, string message_type, string message ) {
|
||||
LogPush( procedure + ";" + message_type + ";" + message );
|
||||
}
|
||||
static void LogPush( string message ) {
|
||||
if ( m_sw == null ) {
|
||||
m_log_file = Path.Combine( Application.StartupPath, "error.log" );
|
||||
m_sw = new StreamWriter( m_log_file, true, Encoding.Unicode );
|
||||
m_sw.WriteLine( "************************************************************************" );
|
||||
m_sw.WriteLine( "Logger started : " + DateTime.Now.ToString() );
|
||||
m_sw.WriteLine( "------------------------------------------------------------------------" );
|
||||
}
|
||||
m_sw.WriteLine( DateTime.Now.ToString() + ";" + message );
|
||||
m_sw.Flush();
|
||||
}
|
||||
|
||||
public static void LogClose() {
|
||||
if ( m_sw != null ) {
|
||||
m_sw.Close();
|
||||
m_sw = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 指定したパスのファイルからイメージを読み込みます
|
||||
/// </summary>
|
||||
/// <param name="fpath">イメージファイルへのパス</param>
|
||||
/// <returns></returns>
|
||||
public static Image ImageFromFile( string fpath ) {
|
||||
Bitmap result = null;
|
||||
if ( File.Exists( fpath ) ) {
|
||||
using ( FileStream fs = new FileStream( fpath, FileMode.Open, FileAccess.Read ) ) {
|
||||
Image temp = Image.FromStream( fs );
|
||||
result = new Bitmap( temp.Width, temp.Height, PixelFormat.Format32bppArgb );
|
||||
using ( Graphics g = Graphics.FromImage( result ) ) {
|
||||
g.DrawImage( temp, 0, 0, temp.Width, temp.Height );
|
||||
}
|
||||
temp.Dispose();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
2653
trunk/LipSync/Common/CurveEditor.cs
Normal file
2653
trunk/LipSync/Common/CurveEditor.cs
Normal file
File diff suppressed because it is too large
Load Diff
68
trunk/LipSync/Common/CurveEditor.designer.cs
generated
Normal file
68
trunk/LipSync/Common/CurveEditor.designer.cs
generated
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* CurveEditor.designer.cs
|
||||
* Copyright (c) 2007-2009 kbinani
|
||||
*
|
||||
* This file is part of LipSync.
|
||||
*
|
||||
* LipSync is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the BSD License.
|
||||
*
|
||||
* LipSync 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.
|
||||
*/
|
||||
namespace CurveEditor {
|
||||
partial class CurveEditor {
|
||||
/// <summary>
|
||||
/// 必要なデザイナ変数です。
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// 使用中のリソースをすべてクリーンアップします。
|
||||
/// </summary>
|
||||
/// <param name="disposing">マネージ リソースが破棄される場合 true、破棄されない場合は false です。</param>
|
||||
protected override void Dispose( bool disposing ) {
|
||||
if ( disposing && (components != null) ) {
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose( disposing );
|
||||
}
|
||||
|
||||
#region コンポーネント デザイナで生成されたコード
|
||||
|
||||
/// <summary>
|
||||
/// デザイナ サポートに必要なメソッドです。このメソッドの内容を
|
||||
/// コード エディタで変更しないでください。
|
||||
/// </summary>
|
||||
private void InitializeComponent() {
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// CurveEditor
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF( 6F, 12F );
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.BackColor = System.Drawing.SystemColors.Control;
|
||||
this.Name = "CurveEditor";
|
||||
this.Size = new System.Drawing.Size( 333, 120 );
|
||||
this.Paint += new System.Windows.Forms.PaintEventHandler( this.CurveEditor_Paint );
|
||||
this.PreviewKeyDown += new System.Windows.Forms.PreviewKeyDownEventHandler( this.CurveEditor_PreviewKeyDown );
|
||||
this.MouseMove += new System.Windows.Forms.MouseEventHandler( this.CurveEditor_MouseMove );
|
||||
this.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler( this.CurveEditor_MouseDoubleClick );
|
||||
this.FontChanged += new System.EventHandler( this.CurveEditor_FontChanged );
|
||||
this.KeyUp += new System.Windows.Forms.KeyEventHandler( this.CurveEditor_KeyUp );
|
||||
this.MouseClick += new System.Windows.Forms.MouseEventHandler( this.CurveEditor_MouseClick );
|
||||
this.MouseDown += new System.Windows.Forms.MouseEventHandler( this.CurveEditor_MouseDown );
|
||||
this.Resize += new System.EventHandler( this.CurveEditor_Resize );
|
||||
this.MouseUp += new System.Windows.Forms.MouseEventHandler( this.CurveEditor_MouseUp );
|
||||
this.KeyDown += new System.Windows.Forms.KeyEventHandler( this.CurveEditor_KeyDown );
|
||||
this.ResumeLayout( false );
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
290
trunk/LipSync/Common/NativeMethods.cs
Normal file
290
trunk/LipSync/Common/NativeMethods.cs
Normal file
@@ -0,0 +1,290 @@
|
||||
/*================================================================================
|
||||
File: NativeMethods.cs
|
||||
|
||||
Summary: This is part of a sample showing how to place Windows Forms controls
|
||||
inside one of the common file dialogs.
|
||||
----------------------------------------------------------------------------------
|
||||
Copyright (C) Microsoft Corporation. All rights reserved.
|
||||
|
||||
This source code is intended only as a supplement to Microsoft Development Tools
|
||||
and/or on-line documentation. See these other materials for detailed information
|
||||
regarding Microsoft code samples.
|
||||
|
||||
This sample is not intended for production use. Code and policy for a production
|
||||
application must be developed to meet the specific data and security requirements
|
||||
of the application.
|
||||
|
||||
THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
|
||||
EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
================================================================================*/
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace ExtensibleDialogs
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the shape of hook procedures that can be called by the OpenFileDialog
|
||||
/// </summary>
|
||||
internal delegate IntPtr OfnHookProc( IntPtr hWnd, UInt16 msg, Int32 wParam, Int32 lParam );
|
||||
|
||||
/// <summary>
|
||||
/// Values that can be placed in the OPENFILENAME structure, we don't use all of them
|
||||
/// </summary>
|
||||
internal class OpenFileNameFlags
|
||||
{
|
||||
public const Int32 ReadOnly = 0x00000001;
|
||||
public const Int32 OverWritePrompt = 0x00000002;
|
||||
public const Int32 HideReadOnly = 0x00000004;
|
||||
public const Int32 NoChangeDir = 0x00000008;
|
||||
public const Int32 ShowHelp = 0x00000010;
|
||||
public const Int32 EnableHook = 0x00000020;
|
||||
public const Int32 EnableTemplate = 0x00000040;
|
||||
public const Int32 EnableTemplateHandle = 0x00000080;
|
||||
public const Int32 NoValidate = 0x00000100;
|
||||
public const Int32 AllowMultiSelect = 0x00000200;
|
||||
public const Int32 ExtensionDifferent = 0x00000400;
|
||||
public const Int32 PathMustExist = 0x00000800;
|
||||
public const Int32 FileMustExist = 0x00001000;
|
||||
public const Int32 CreatePrompt = 0x00002000;
|
||||
public const Int32 ShareAware = 0x00004000;
|
||||
public const Int32 NoReadOnlyReturn = 0x00008000;
|
||||
public const Int32 NoTestFileCreate = 0x00010000;
|
||||
public const Int32 NoNetworkButton = 0x00020000;
|
||||
public const Int32 NoLongNames = 0x00040000;
|
||||
public const Int32 Explorer = 0x00080000;
|
||||
public const Int32 NoDereferenceLinks = 0x00100000;
|
||||
public const Int32 LongNames = 0x00200000;
|
||||
public const Int32 EnableIncludeNotify = 0x00400000;
|
||||
public const Int32 EnableSizing = 0x00800000;
|
||||
public const Int32 DontAddToRecent = 0x02000000;
|
||||
public const Int32 ForceShowHidden = 0x10000000;
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Values that can be placed in the FlagsEx field of the OPENFILENAME structure
|
||||
/// </summary>
|
||||
internal class OpenFileNameFlagsEx
|
||||
{
|
||||
public const Int32 NoPlacesBar = 0x00000001;
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// A small subset of the window messages that can be sent to the OpenFileDialog
|
||||
/// These are just the ones that this implementation is interested in
|
||||
/// </summary>
|
||||
internal class WindowMessage
|
||||
{
|
||||
public const UInt16 InitDialog = 0x0110;
|
||||
public const UInt16 Size = 0x0005;
|
||||
public const UInt16 Notify = 0x004E;
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// The possible notification messages that can be generated by the OpenFileDialog
|
||||
/// We only look for CDN_SELCHANGE
|
||||
/// </summary>
|
||||
internal class CommonDlgNotification
|
||||
{
|
||||
private const UInt16 First = unchecked((UInt16)((UInt16)0 - (UInt16)601));
|
||||
|
||||
public const UInt16 InitDone = (First - 0x0000);
|
||||
public const UInt16 SelChange = (First - 0x0001);
|
||||
public const UInt16 FolderChange = (First - 0x0002);
|
||||
public const UInt16 ShareViolation = (First - 0x0003);
|
||||
public const UInt16 Help = (First - 0x0004);
|
||||
public const UInt16 FileOk = (First - 0x0005);
|
||||
public const UInt16 TypeChange = (First - 0x0006);
|
||||
public const UInt16 IncludeItem = (First - 0x0007);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Messages that can be send to the common dialogs
|
||||
/// We only use CDM_GETFILEPATH
|
||||
/// </summary>
|
||||
internal class CommonDlgMessage {
|
||||
private const UInt16 User = 0x0400;
|
||||
private const UInt16 First = User + 100;
|
||||
private const UInt16 Last = User + 200;
|
||||
public const UInt16 GetSpec = First;
|
||||
public const UInt16 GetFilePath = First + 0x0001;
|
||||
public const UInt16 GetFolderPath = First + 0x0002;
|
||||
public const UInt16 GetFolderIDList = First + 0x0003;
|
||||
public const UInt16 SetControlText = First + 0x0004;
|
||||
public const UInt16 HideControl = First + 0x0005;
|
||||
public const UInt16 SetDefExt = First + 0x0006;
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// See the documentation for OPENFILENAME
|
||||
/// </summary>
|
||||
internal struct OpenFileName
|
||||
{
|
||||
public Int32 lStructSize;
|
||||
public IntPtr hwndOwner;
|
||||
public IntPtr hInstance;
|
||||
public IntPtr lpstrFilter;
|
||||
public IntPtr lpstrCustomFilter;
|
||||
public Int32 nMaxCustFilter;
|
||||
public Int32 nFilterIndex;
|
||||
public IntPtr lpstrFile;
|
||||
public Int32 nMaxFile;
|
||||
public IntPtr lpstrFileTitle;
|
||||
public Int32 nMaxFileTitle;
|
||||
public IntPtr lpstrInitialDir;
|
||||
public IntPtr lpstrTitle;
|
||||
public Int32 Flags;
|
||||
public Int16 nFileOffset;
|
||||
public Int16 nFileExtension;
|
||||
public IntPtr lpstrDefExt;
|
||||
public Int32 lCustData;
|
||||
public OfnHookProc lpfnHook;
|
||||
public IntPtr lpTemplateName;
|
||||
public IntPtr pvReserved;
|
||||
public Int32 dwReserved;
|
||||
public Int32 FlagsEx;
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Part of the notification messages sent by the common dialogs
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
internal struct NMHDR
|
||||
{
|
||||
[FieldOffset(0)] public IntPtr hWndFrom;
|
||||
[FieldOffset(4)] public UInt16 idFrom;
|
||||
[FieldOffset(8)] public UInt16 code;
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Part of the notification messages sent by the common dialogs
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
internal struct OfNotify
|
||||
{
|
||||
[FieldOffset(0)] public NMHDR hdr;
|
||||
[FieldOffset(12)] public IntPtr ipOfn;
|
||||
[FieldOffset(16)] public IntPtr ipFile;
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Win32 window style constants
|
||||
/// We use them to set up our child window
|
||||
/// </summary>
|
||||
internal class DlgStyle
|
||||
{
|
||||
public const Int32 DsSetFont = 0x00000040;
|
||||
public const Int32 Ds3dLook = 0x00000004;
|
||||
public const Int32 DsControl = 0x00000400;
|
||||
public const Int32 WsChild = 0x40000000;
|
||||
public const Int32 WsClipSiblings = 0x04000000;
|
||||
public const Int32 WsVisible = 0x10000000;
|
||||
public const Int32 WsGroup = 0x00020000;
|
||||
public const Int32 SsNotify = 0x00000100;
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Win32 "extended" window style constants
|
||||
/// </summary>
|
||||
internal class ExStyle
|
||||
{
|
||||
public const Int32 WsExNoParentNotify = 0x00000004;
|
||||
public const Int32 WsExControlParent = 0x00010000;
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// An in-memory Win32 dialog template
|
||||
/// Note: this has a very specific structure with a single static "label" control
|
||||
/// See documentation for DLGTEMPLATE and DLGITEMTEMPLATE
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal class DlgTemplate
|
||||
{
|
||||
// The dialog template - see documentation for DLGTEMPLATE
|
||||
public Int32 style = DlgStyle.Ds3dLook | DlgStyle.DsControl | DlgStyle.WsChild | DlgStyle.WsClipSiblings | DlgStyle.SsNotify;
|
||||
public Int32 extendedStyle = ExStyle.WsExControlParent;
|
||||
public Int16 numItems = 1;
|
||||
public Int16 x = 0;
|
||||
public Int16 y = 0;
|
||||
public Int16 cx = 0;
|
||||
public Int16 cy = 0;
|
||||
public Int16 reservedMenu = 0;
|
||||
public Int16 reservedClass = 0;
|
||||
public Int16 reservedTitle = 0;
|
||||
|
||||
// Single dlg item, must be dword-aligned - see documentation for DLGITEMTEMPLATE
|
||||
public Int32 itemStyle = DlgStyle.WsChild;
|
||||
public Int32 itemExtendedStyle = ExStyle.WsExNoParentNotify;
|
||||
public Int16 itemX = 0;
|
||||
public Int16 itemY = 0;
|
||||
public Int16 itemCx = 0;
|
||||
public Int16 itemCy = 0;
|
||||
public Int16 itemId = 0;
|
||||
public UInt16 itemClassHdr = 0xffff; // we supply a constant to indicate the class of this control
|
||||
public Int16 itemClass = 0x0082; // static label control
|
||||
public Int16 itemText = 0x0000; // no text for this control
|
||||
public Int16 itemData = 0x0000; // no creation data for this control
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// The rectangle structure used in Win32 API calls
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct RECT
|
||||
{
|
||||
public int left;
|
||||
public int top;
|
||||
public int right;
|
||||
public int bottom;
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// The point structure used in Win32 API calls
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct POINT
|
||||
{
|
||||
public int X;
|
||||
public int Y;
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Contains all of the p/invoke declarations for the Win32 APIs used in this sample
|
||||
/// </summary>
|
||||
public class NativeMethods
|
||||
{
|
||||
|
||||
[DllImport("User32.dll", CharSet = CharSet.Unicode)]
|
||||
internal static extern IntPtr GetDlgItem( IntPtr hWndDlg, Int16 Id );
|
||||
|
||||
[DllImport("User32.dll", CharSet = CharSet.Unicode)]
|
||||
internal static extern IntPtr GetParent( IntPtr hWnd );
|
||||
|
||||
[DllImport("User32.dll", CharSet = CharSet.Unicode)]
|
||||
internal static extern IntPtr SetParent( IntPtr hWndChild, IntPtr hWndNewParent );
|
||||
|
||||
[DllImport("User32.dll", CharSet = CharSet.Unicode)]
|
||||
internal static extern UInt32 SendMessage( IntPtr hWnd, UInt32 msg, UInt32 wParam, StringBuilder buffer );
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
|
||||
internal static extern int GetWindowRect( IntPtr hWnd, ref RECT rc );
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
|
||||
internal static extern int GetClientRect( IntPtr hWnd, ref RECT rc );
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
|
||||
internal static extern bool ScreenToClient( IntPtr hWnd, ref POINT pt );
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
|
||||
internal static extern bool MoveWindow( IntPtr hWnd, int X, int Y, int Width, int Height, bool repaint );
|
||||
|
||||
[DllImport("ComDlg32.dll", CharSet = CharSet.Unicode)]
|
||||
internal static extern bool GetOpenFileName( ref OpenFileName ofn );
|
||||
|
||||
[DllImport("ComDlg32.dll", CharSet = CharSet.Unicode)]
|
||||
internal static extern Int32 CommDlgExtendedError();
|
||||
|
||||
}
|
||||
}
|
||||
45
trunk/LipSync/Common/NumericUpDownEx.Designer.cs
generated
Normal file
45
trunk/LipSync/Common/NumericUpDownEx.Designer.cs
generated
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* NumericUpDownEx.Designer.cs
|
||||
* Copyright (c) 2007-2009 kbinani
|
||||
*
|
||||
* This file is part of LipSync.
|
||||
*
|
||||
* LipSync is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the BSD License.
|
||||
*
|
||||
* LipSync 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.
|
||||
*/
|
||||
namespace LipSync {
|
||||
partial class NumericUpDownEx {
|
||||
/// <summary>
|
||||
/// 必要なデザイナ変数です。
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// 使用中のリソースをすべてクリーンアップします。
|
||||
/// </summary>
|
||||
/// <param name="disposing">マネージ リソースが破棄される場合 true、破棄されない場合は false です。</param>
|
||||
protected override void Dispose( bool disposing ) {
|
||||
if ( disposing && (components != null) ) {
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose( disposing );
|
||||
}
|
||||
|
||||
#region コンポーネント デザイナで生成されたコード
|
||||
|
||||
/// <summary>
|
||||
/// デザイナ サポートに必要なメソッドです。このメソッドの内容を
|
||||
/// コード エディタで変更しないでください。
|
||||
/// </summary>
|
||||
private void InitializeComponent() {
|
||||
components = new System.ComponentModel.Container();
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
44
trunk/LipSync/Common/NumericUpDownEx.cs
Normal file
44
trunk/LipSync/Common/NumericUpDownEx.cs
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* NumericUpDownEx.cs
|
||||
* Copyright (c) 2007-2009 kbinani
|
||||
*
|
||||
* This file is part of LipSync.
|
||||
*
|
||||
* LipSync is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the BSD License.
|
||||
*
|
||||
* LipSync 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.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
//using System.Data;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace LipSync {
|
||||
/// <summary>
|
||||
/// MouseWheelでIncrementずつ値を増減させることのできるNumericUpDown
|
||||
/// </summary>
|
||||
public partial class NumericUpDownEx : NumericUpDown {
|
||||
public NumericUpDownEx() {
|
||||
InitializeComponent();
|
||||
}
|
||||
protected override void OnMouseWheel( MouseEventArgs e ) {
|
||||
decimal new_val;
|
||||
if ( e.Delta > 0 ) {
|
||||
new_val = this.Value + this.Increment;
|
||||
} else if ( e.Delta < 0 ) {
|
||||
new_val = this.Value - this.Increment;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
if ( this.Minimum <= new_val && new_val <= this.Maximum ) {
|
||||
this.Value = new_val;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
506
trunk/LipSync/Common/OpenFileDialog.cs
Normal file
506
trunk/LipSync/Common/OpenFileDialog.cs
Normal file
@@ -0,0 +1,506 @@
|
||||
/*================================================================================
|
||||
File: OpenFileDialog.cs
|
||||
|
||||
Summary: This is part of a sample showing how to place Windows Forms controls
|
||||
inside one of the common file dialogs.
|
||||
----------------------------------------------------------------------------------
|
||||
Copyright (C) Microsoft Corporation. All rights reserved.
|
||||
|
||||
This source code is intended only as a supplement to Microsoft Development Tools
|
||||
and/or on-line documentation. See these other materials for detailed information
|
||||
regarding Microsoft code samples.
|
||||
|
||||
This sample is not intended for production use. Code and policy for a production
|
||||
application must be developed to meet the specific data and security requirements
|
||||
of the application.
|
||||
|
||||
THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
|
||||
EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
================================================================================*/
|
||||
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
|
||||
namespace ExtensibleDialogs {
|
||||
/// <summary>
|
||||
/// The extensible OpenFileDialog
|
||||
/// </summary>
|
||||
public class OpenFileDialog : IDisposable {
|
||||
// The maximum number of characters permitted in a path
|
||||
private const int _MAX_PATH = 260;
|
||||
|
||||
// The "control ID" of the content window inside the OpenFileDialog
|
||||
// See the accompanying article to learn how I discovered it
|
||||
private const int _CONTENT_PANEL_ID = 0x0461;
|
||||
|
||||
// A constant that determines the spacing between panels inside the OpenFileDialog
|
||||
private const int _PANEL_GAP_FACTOR = 3;
|
||||
|
||||
/// <summary>
|
||||
/// Clients can implement handlers of this type to catch "selection changed" events
|
||||
/// </summary>
|
||||
public delegate void SelectionChangedHandler( string path );
|
||||
|
||||
/// <summary>
|
||||
/// This event is fired whenever the user selects an item in the dialog
|
||||
/// </summary>
|
||||
public event SelectionChangedHandler SelectionChanged;
|
||||
|
||||
public delegate void FolderChangedHandler( string path );
|
||||
public event FolderChangedHandler FolderChanged;
|
||||
|
||||
// unmanaged memory buffers to hold the file name (with and without full path)
|
||||
private IntPtr _fileNameBuffer;
|
||||
private IntPtr _fileTitleBuffer;
|
||||
private IntPtr _initialDirBuffer;
|
||||
|
||||
// user-supplied control that gets placed inside the OpenFileDialog
|
||||
private System.Windows.Forms.Control _userControl;
|
||||
|
||||
// unmanaged memory buffer that holds the Win32 dialog template
|
||||
private IntPtr _ipTemplate;
|
||||
|
||||
private string _filter;
|
||||
private string _fileName;
|
||||
private string _defaultExtension;
|
||||
private int _filterIndex;
|
||||
private short _fileOffset;
|
||||
private short _fileExtension;
|
||||
private string _initialDir;
|
||||
|
||||
public string InitialDirectory {
|
||||
get {
|
||||
return _initialDir;
|
||||
}
|
||||
set {
|
||||
_initialDir = value;
|
||||
if ( !Path.IsPathRooted( _initialDir ) ) {
|
||||
if ( !Directory.Exists( _initialDir ) ) {
|
||||
_initialDir = Path.GetDirectoryName( _initialDir );
|
||||
}
|
||||
}
|
||||
_fileName = "";
|
||||
UnicodeEncoding ue = new UnicodeEncoding();
|
||||
byte[] zero = new byte[2 * _MAX_PATH];
|
||||
for ( int i = 0; i < 2 * _MAX_PATH; i++ ) {
|
||||
zero[i] = 0;
|
||||
}
|
||||
Marshal.Copy( zero, 0, _initialDirBuffer, 2 * _MAX_PATH );
|
||||
Marshal.Copy( zero, 0, _fileNameBuffer, 2 * _MAX_PATH );
|
||||
if ( _initialDir.Length > 0 ) {
|
||||
byte[] initial_dir_buffer = ue.GetBytes( _initialDir );
|
||||
Marshal.Copy( initial_dir_buffer, 0, _initialDirBuffer, initial_dir_buffer.Length );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public int FilterIndex {
|
||||
get {
|
||||
return _filterIndex;
|
||||
}
|
||||
set {
|
||||
_filterIndex = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public OpenFileDialog( System.Windows.Forms.Control userControl )
|
||||
: this( "", "", "", userControl ) {
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Sets up the data structures necessary to display the OpenFileDialog
|
||||
/// </summary>
|
||||
/// <param name="defaultExtension">The file extension to use if the user doesn't specify one (no "." required)</param>
|
||||
/// <param name="fileName">You can specify a filename to appear in the dialog, although the user can change it</param>
|
||||
/// <param name="filter">See the documentation for the OPENFILENAME structure for a description of filter strings</param>
|
||||
/// <param name="userPanel">Any Windows Forms control, it will be placed inside the OpenFileDialog</param>
|
||||
private OpenFileDialog( string defaultExtension, string fileName, string filter, System.Windows.Forms.Control userControl ) {
|
||||
_filter = filter;
|
||||
_fileName = fileName;
|
||||
_defaultExtension = defaultExtension;
|
||||
|
||||
// LipSync Character Config(*.lsc,content.xml)|*.lsc;content.xml|All Files(*.*)|*.*
|
||||
// ↁE
|
||||
// LipSync Character Config(*.lsc,content.xml)\0*.lsc;content.xml\0All Files(*.*)\0*.*\0\0
|
||||
filter = filter.Replace( "|", "\0" ) + "\0\0";
|
||||
|
||||
// Need two buffers in unmanaged memory to hold the filename
|
||||
// Note: the multiplication by 2 is to allow for Unicode (16-bit) characters
|
||||
_fileNameBuffer = Marshal.AllocCoTaskMem( 2 * _MAX_PATH );
|
||||
_fileTitleBuffer = Marshal.AllocCoTaskMem( 2 * _MAX_PATH );
|
||||
_initialDirBuffer = Marshal.AllocCoTaskMem( 2 * _MAX_PATH );
|
||||
|
||||
// Zero these two buffers
|
||||
byte[] zeroBuffer = new byte[2 * (_MAX_PATH + 1)];
|
||||
for ( int i = 0; i < 2 * (_MAX_PATH + 1); i++ ) {
|
||||
zeroBuffer[i] = 0;
|
||||
}
|
||||
Marshal.Copy( zeroBuffer, 0, _fileNameBuffer, 2 * _MAX_PATH );
|
||||
Marshal.Copy( zeroBuffer, 0, _fileTitleBuffer, 2 * _MAX_PATH );
|
||||
Marshal.Copy( zeroBuffer, 0, _initialDirBuffer, 2 * _MAX_PATH );
|
||||
|
||||
_filterIndex = 0;
|
||||
_fileOffset = 0;
|
||||
_fileExtension = 0;
|
||||
|
||||
// keep a reference to the user-supplied control
|
||||
_userControl = userControl;
|
||||
}
|
||||
|
||||
|
||||
public string FileName {
|
||||
get {
|
||||
return _fileName;
|
||||
}
|
||||
set {
|
||||
if ( value == null ) {
|
||||
return;
|
||||
}
|
||||
_fileName = value;
|
||||
string folder;
|
||||
if ( Path.IsPathRooted( _fileName ) ) {
|
||||
folder = _fileName;
|
||||
_fileName = "";
|
||||
} else {
|
||||
if ( Directory.Exists( _fileName ) ) {
|
||||
folder = _fileName;
|
||||
_fileName = "";
|
||||
} else {
|
||||
if ( _fileName != "" ) {
|
||||
folder = Path.GetDirectoryName( _fileName );
|
||||
} else {
|
||||
folder = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
#if DEBUG
|
||||
LipSync.Common.DebugWriteLine( "FileName.set(); folder=" + folder );
|
||||
LipSync.Common.DebugWriteLine( "FileName.set(); _fileName=" + _fileName );
|
||||
#endif
|
||||
byte[] zero = new byte[2 * _MAX_PATH];
|
||||
for ( int i = 0; i < 2 * _MAX_PATH; i++ ) {
|
||||
zero[i] = 0;
|
||||
}
|
||||
Marshal.Copy( zero, 0, _fileNameBuffer, 2 * _MAX_PATH );
|
||||
Marshal.Copy( zero, 0, _initialDirBuffer, 2 * _MAX_PATH );
|
||||
|
||||
UnicodeEncoding ue = new UnicodeEncoding();
|
||||
if ( _fileName.Length > 0 ) {
|
||||
byte[] file_name_bytes = ue.GetBytes( _fileName );
|
||||
Marshal.Copy( file_name_bytes, 0, _fileNameBuffer, file_name_bytes.Length );
|
||||
}
|
||||
|
||||
if ( folder.Length > 0 ) {
|
||||
byte[] initial_dir_bytes = ue.GetBytes( folder );
|
||||
Marshal.Copy( initial_dir_bytes, 0, _initialDirBuffer, initial_dir_bytes.Length );
|
||||
}
|
||||
#if DEBUG
|
||||
LipSync.Common.DebugWriteLine( "FileName.set(); _fileNameBuffer=" + Marshal.PtrToStringUni( _fileNameBuffer ) );
|
||||
LipSync.Common.DebugWriteLine( "FileName.set(); _initialDir=" + Marshal.PtrToStringUni( _initialDirBuffer ) );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public string Filter {
|
||||
get {
|
||||
return _filter;
|
||||
}
|
||||
set {
|
||||
_filter = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public string DefaultExt {
|
||||
get {
|
||||
return _defaultExtension;
|
||||
}
|
||||
set {
|
||||
_defaultExtension = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The finalizer will release the unmanaged memory, if I should forget to call Dispose
|
||||
/// </summary>
|
||||
~OpenFileDialog() {
|
||||
Dispose( false );
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Display the OpenFileDialog and allow user interaction
|
||||
/// </summary>
|
||||
/// <returns>true if the user clicked OK, false if they clicked cancel (or close)</returns>
|
||||
public System.Windows.Forms.DialogResult ShowDialog() {
|
||||
// Create an in-memory Win32 dialog template; this will be a "child" window inside the FileOpenDialog
|
||||
// We have no use for this child window, except that its presence allows us to capture events when
|
||||
// the user interacts with the FileOpenDialog
|
||||
_ipTemplate = BuildDialogTemplate();
|
||||
|
||||
// Populate the OPENFILENAME structure
|
||||
// The flags specified are the minimal set to get the appearance and behaviour we need
|
||||
OpenFileName ofn = new OpenFileName();
|
||||
ofn.lStructSize = Marshal.SizeOf( ofn );
|
||||
ofn.lpstrFile = _fileNameBuffer;
|
||||
ofn.nMaxFile = _MAX_PATH;
|
||||
ofn.lpstrDefExt = Marshal.StringToCoTaskMemUni( _defaultExtension );
|
||||
ofn.lpstrFileTitle = _fileTitleBuffer;
|
||||
ofn.nMaxFileTitle = _MAX_PATH;
|
||||
string filter = _filter.Replace( "|", "\0" ) + "\0\0";
|
||||
ofn.lpstrFilter = Marshal.StringToCoTaskMemUni( filter );
|
||||
ofn.Flags = OpenFileNameFlags.EnableHook | OpenFileNameFlags.EnableTemplateHandle | OpenFileNameFlags.EnableSizing | OpenFileNameFlags.Explorer;
|
||||
ofn.hInstance = _ipTemplate;
|
||||
ofn.lpfnHook = new OfnHookProc( MyHookProc );
|
||||
ofn.lpstrInitialDir = _initialDirBuffer;
|
||||
ofn.nFilterIndex = _filterIndex;
|
||||
ofn.nFileOffset = _fileOffset;
|
||||
ofn.nFileExtension = _fileExtension;
|
||||
|
||||
// copy initial file name into unmanaged memory buffer
|
||||
UnicodeEncoding ue = new UnicodeEncoding();
|
||||
byte[] fileNameBytes = ue.GetBytes( _fileName );
|
||||
Marshal.Copy( fileNameBytes, 0, _fileNameBuffer, fileNameBytes.Length );
|
||||
Marshal.Copy( fileNameBytes, 0, _initialDirBuffer, fileNameBytes.Length );
|
||||
|
||||
if ( NativeMethods.GetOpenFileName( ref ofn ) ) {
|
||||
_fileName = Marshal.PtrToStringUni( _fileNameBuffer );
|
||||
_filterIndex = ofn.nFilterIndex;
|
||||
byte[] file_name_buffer = ue.GetBytes( _fileName );
|
||||
Marshal.Copy( file_name_buffer, 0, _initialDirBuffer, file_name_buffer.Length );
|
||||
_fileOffset = ofn.nFileOffset;
|
||||
_fileExtension = ofn.nFileExtension;
|
||||
return System.Windows.Forms.DialogResult.OK;
|
||||
} else {
|
||||
return System.Windows.Forms.DialogResult.Cancel;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Builds an in-memory Win32 dialog template. See documentation for DLGTEMPLATE.
|
||||
/// </summary>
|
||||
/// <returns>a pointer to an unmanaged memory buffer containing the dialog template</returns>
|
||||
private IntPtr BuildDialogTemplate() {
|
||||
// We must place this child window inside the standard FileOpenDialog in order to get any
|
||||
// notifications sent to our hook procedure. Also, this child window must contain at least
|
||||
// one control. We make no direct use of the child window, or its control.
|
||||
|
||||
// Set up the contents of the DLGTEMPLATE
|
||||
DlgTemplate template = new DlgTemplate();
|
||||
|
||||
// Allocate some unmanaged memory for the template structure, and copy it in
|
||||
IntPtr ipTemplate = Marshal.AllocCoTaskMem( Marshal.SizeOf( template ) );
|
||||
Marshal.StructureToPtr( template, ipTemplate, true );
|
||||
return ipTemplate;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The hook procedure for window messages generated by the FileOpenDialog
|
||||
/// </summary>
|
||||
/// <param name="hWnd">the handle of the window at which this message is targeted</param>
|
||||
/// <param name="msg">the message identifier</param>
|
||||
/// <param name="wParam">message-specific parameter data</param>
|
||||
/// <param name="lParam">mess-specific parameter data</param>
|
||||
/// <returns></returns>
|
||||
public IntPtr MyHookProc( IntPtr hWnd, UInt16 msg, Int32 wParam, Int32 lParam ) {
|
||||
if ( hWnd == IntPtr.Zero )
|
||||
return IntPtr.Zero;
|
||||
|
||||
// Behaviour is dependant on the message received
|
||||
switch ( msg ) {
|
||||
// We're not interested in every possible message; just return a NULL for those we don't care about
|
||||
default: {
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
|
||||
// WM_INITDIALOG - at this point the OpenFileDialog exists, so we pull the user-supplied control
|
||||
// into the FileOpenDialog now, using the SetParent API.
|
||||
case WindowMessage.InitDialog: {
|
||||
if( _userControl != null ){
|
||||
IntPtr hWndParent = NativeMethods.GetParent( hWnd );
|
||||
NativeMethods.SetParent( _userControl.Handle, hWndParent );
|
||||
}
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
|
||||
// WM_SIZE - the OpenFileDialog has been resized, so we'll resize the content and user-supplied
|
||||
// panel to fit nicely
|
||||
case WindowMessage.Size: {
|
||||
FindAndResizePanels( hWnd );
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
|
||||
// WM_NOTIFY - we're only interested in the CDN_SELCHANGE notification message:
|
||||
// we grab the currently-selected filename and fire our event
|
||||
case WindowMessage.Notify: {
|
||||
IntPtr ipNotify = new IntPtr( lParam );
|
||||
OfNotify ofNot = (OfNotify)Marshal.PtrToStructure( ipNotify, typeof( OfNotify ) );
|
||||
UInt16 code = ofNot.hdr.code;
|
||||
if ( code == CommonDlgNotification.SelChange ) {
|
||||
// This is the first time we can rely on the presence of the content panel
|
||||
// Resize the content and user-supplied panels to fit nicely
|
||||
FindAndResizePanels( hWnd );
|
||||
|
||||
// get the newly-selected path
|
||||
IntPtr hWndParent = NativeMethods.GetParent( hWnd );
|
||||
StringBuilder pathBuffer = new StringBuilder( _MAX_PATH );
|
||||
UInt32 ret = NativeMethods.SendMessage( hWndParent, CommonDlgMessage.GetFilePath, _MAX_PATH, pathBuffer );
|
||||
string path = pathBuffer.ToString();
|
||||
|
||||
// copy the string into the path buffer
|
||||
byte[] zero = new byte[2 * _MAX_PATH];
|
||||
for ( int i = 0; i < 2 * _MAX_PATH; i++ ) {
|
||||
zero[i] = 0;
|
||||
}
|
||||
Marshal.Copy( zero, 0, _fileNameBuffer, 2 * _MAX_PATH );
|
||||
UnicodeEncoding ue = new UnicodeEncoding();
|
||||
byte[] pathBytes = ue.GetBytes( path );
|
||||
Marshal.Copy( pathBytes, 0, _fileNameBuffer, pathBytes.Length );
|
||||
|
||||
_fileName = path;
|
||||
#if DEBUG
|
||||
LipSync.Common.DebugWriteLine( "ExtensibleDialog.OpenFiledialog.MyHookProc; SelChange; _fileName=" + path );
|
||||
#endif
|
||||
// fire selection-changed event
|
||||
if ( SelectionChanged != null ) {
|
||||
SelectionChanged( path );
|
||||
}
|
||||
} else if ( code == CommonDlgNotification.FolderChange ) {
|
||||
// This is the first time we can rely on the presence of the content panel
|
||||
// Resize the content and user-supplied panels to fit nicely
|
||||
FindAndResizePanels( hWnd );
|
||||
|
||||
// get the newly-selected path
|
||||
IntPtr hWndParent = NativeMethods.GetParent( hWnd );
|
||||
StringBuilder pathBuffer = new StringBuilder( _MAX_PATH );
|
||||
UInt32 ret = NativeMethods.SendMessage( hWndParent, CommonDlgMessage.GetFolderPath, _MAX_PATH, pathBuffer );
|
||||
string path = pathBuffer.ToString();
|
||||
|
||||
// copy the string into the path buffer
|
||||
byte[] zero = new byte[2 * _MAX_PATH];
|
||||
for ( int i = 0; i < 2 * _MAX_PATH; i++ ) {
|
||||
zero[i] = 0;
|
||||
}
|
||||
Marshal.Copy( zero, 0, _initialDirBuffer, 2 * _MAX_PATH );
|
||||
Marshal.Copy( zero, 0, _fileNameBuffer, 2 * _MAX_PATH );
|
||||
UnicodeEncoding ue = new UnicodeEncoding();
|
||||
byte[] pathBytes = ue.GetBytes( path );
|
||||
Marshal.Copy( pathBytes, 0, _initialDirBuffer, pathBytes.Length );
|
||||
|
||||
// fire selection-changed event
|
||||
if ( FolderChanged != null ) {
|
||||
FolderChanged( path );
|
||||
}
|
||||
}
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Layout the content of the OpenFileDialog, according to the overall size of the dialog
|
||||
/// </summary>
|
||||
/// <param name="hWnd">handle of window that received the WM_SIZE message</param>
|
||||
private void FindAndResizePanels( IntPtr hWnd ) {
|
||||
// The FileOpenDialog is actually of the parent of the specified window
|
||||
IntPtr hWndParent = NativeMethods.GetParent( hWnd );
|
||||
|
||||
// The "content" window is the one that displays the filenames, tiles, etc.
|
||||
// The _CONTENT_PANEL_ID is a magic number - see the accompanying text to learn
|
||||
// how I discovered it.
|
||||
IntPtr hWndContent = NativeMethods.GetDlgItem( hWndParent, _CONTENT_PANEL_ID );
|
||||
|
||||
Rectangle rcClient = new Rectangle( 0, 0, 0, 0 );
|
||||
Rectangle rcContent = new Rectangle( 0, 0, 0, 0 );
|
||||
|
||||
// Get client rectangle of dialog
|
||||
RECT rcTemp = new RECT();
|
||||
NativeMethods.GetClientRect( hWndParent, ref rcTemp );
|
||||
rcClient.X = rcTemp.left;
|
||||
rcClient.Y = rcTemp.top;
|
||||
rcClient.Width = rcTemp.right - rcTemp.left;
|
||||
rcClient.Height = rcTemp.bottom - rcTemp.top;
|
||||
|
||||
// The content window may not be present when the dialog first appears
|
||||
if ( hWndContent != IntPtr.Zero ) {
|
||||
// Find the dimensions of the content panel
|
||||
RECT rc = new RECT();
|
||||
NativeMethods.GetWindowRect( hWndContent, ref rc );
|
||||
|
||||
// Translate these dimensions into the dialog's coordinate system
|
||||
POINT topLeft;
|
||||
topLeft.X = rc.left;
|
||||
topLeft.Y = rc.top;
|
||||
NativeMethods.ScreenToClient( hWndParent, ref topLeft );
|
||||
POINT bottomRight;
|
||||
bottomRight.X = rc.right;
|
||||
bottomRight.Y = rc.bottom;
|
||||
NativeMethods.ScreenToClient( hWndParent, ref bottomRight );
|
||||
rcContent.X = topLeft.X;
|
||||
rcContent.Width = bottomRight.X - topLeft.X;
|
||||
rcContent.Y = topLeft.Y;
|
||||
rcContent.Height = bottomRight.Y - topLeft.Y;
|
||||
|
||||
// Shrink content panel's width
|
||||
int width = rcClient.Right - rcContent.Left;
|
||||
if ( _userControl != null ) {
|
||||
rcContent.Width = (width / 2) + _PANEL_GAP_FACTOR;
|
||||
} else {
|
||||
rcContent.Width = width + _PANEL_GAP_FACTOR;
|
||||
}
|
||||
NativeMethods.MoveWindow( hWndContent, rcContent.Left, rcContent.Top, rcContent.Width, rcContent.Height, true );
|
||||
}
|
||||
|
||||
if( _userControl != null ){
|
||||
// Position the user-supplied control alongside the content panel
|
||||
Rectangle rcUser = new Rectangle( rcContent.Right + (2 * _PANEL_GAP_FACTOR), rcContent.Top, rcClient.Right - rcContent.Right - (3 * _PANEL_GAP_FACTOR), rcContent.Bottom - rcContent.Top );
|
||||
NativeMethods.MoveWindow( _userControl.Handle, rcUser.X, rcUser.Y, rcUser.Width, rcUser.Height, true );
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// returns the path currently selected by the user inside the OpenFileDialog
|
||||
/// </summary>
|
||||
public string SelectedPath {
|
||||
get {
|
||||
return Marshal.PtrToStringUni( _fileNameBuffer );
|
||||
}
|
||||
}
|
||||
|
||||
#region IDisposable Members
|
||||
|
||||
public void Dispose() {
|
||||
Dispose( true );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Free any unamanged memory used by this instance of OpenFileDialog
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if called by Dispose, false otherwise</param>
|
||||
public void Dispose( bool disposing ) {
|
||||
if ( disposing ) {
|
||||
GC.SuppressFinalize( this );
|
||||
}
|
||||
|
||||
Marshal.FreeCoTaskMem( _fileNameBuffer );
|
||||
Marshal.FreeCoTaskMem( _fileTitleBuffer );
|
||||
Marshal.FreeCoTaskMem( _initialDirBuffer );
|
||||
Marshal.FreeCoTaskMem( _ipTemplate );
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user