الجزء الاول – ايجاد انواع المصادر داخل المكتبة
من خلال هذة السلسلة سنوضح كيفية التعامل مع ملفات المصادر Win32 Resources.
Resources يتم دمجة او حقنة داخل الملف التنفيذي exe او dll ويتكون من صور "Bitmap" او اشكال الماوس "Cursor" او ايقونات "Icon" او بيانات اخري يتم تعريفها من قبل المبرمج وهذة بعض انواع المصادر المعرفة من قبل الويندوز.
RT_CURSOR = 1, // Hardware-dependent cursor resource. RT_BITMAP = 2, // Bitmap resource. RT_ICON = 3, // Hardware-dependent icon resource. RT_MENU = 4, // Menu resource. RT_DIALOG = 5, // Dialog box. RT_STRING = 6, // String-table entry. RT_FONTDIR = 7, // Font directory resource. RT_FONT = 8, // Font resource. RT_ACCELERATOR = 9, // Accelerator table. RT_RCDATA = 10, // Application-defined resource (raw data). RT_MESSAGETABLE = 11, // Message-table entry. RT_GROUP_CURSOR = 12, // Hardware-independent cursor resource. RT_GROUP_ICON = 14, // Hardware-independent icon resource. RT_VERSION = 16, // Version resource. RT_DLGINCLUDE = 17, // Allows a resource editing tool to associate a string with an .rc file. RT_PLUGPLAY = 19, // Plug and Play resource. RT_VXD = 20, // VXD. RT_ANICURSOR = 21, // Animated cursor. RT_ANIICON = 22, // Animated icon. RT_HTML = 23, // HTML. RT_MANIFEST = 24 // Microsoft Windows XP: Side-by-Side Assembly XML Manifest. */
ويتم ايجادالانواع من خلال دوال API والموجودة بمكتبة Kernel32.dll
وفيما يلي عرض الدوال المستخدمة حسب الترتيب.
تقوم هذة الدالة LoadLibraryEx بأيجاد مقبض الملف و تحميلة, ومن ثم نقوم بتحريرها من خلال الدالة FreeLibrary
[Flags]
internal enum LoadLibraryFlags
{
DONT_RESOLVE_DLL_REFERENCES = 0x00000001,
LOAD_LIBRARY_AS_DATAFILE = 0x00000002,
LOAD_WITH_ALTERED_SEARCH_PATH = 0x00000008,
LOAD_IGNORE_CODE_AUTHZ_LEVEL = 0x00000010
}
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
internal extern static IntPtr LoadLibraryEx(
[In] [MarshalAs(UnmanagedType.LPTStr)]string lpLibFileName,
[In] IntPtr hFile,
[In] LoadLibraryFlags dwFlags);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal extern static bool FreeLibrary(
[In] IntPtr hModule);الداله EnumResourceTypes تقم بأرجاع انواع ملفات المصادر المتاحة,
وتحتاج هذة الدالة الي انشاء delegate ليتم ارسال البيانات من خلالها.
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal extern static bool EnumResourceTypes(
[In] IntPtr hModule,
[In] EnumResTypeProc lpEnumFunc,
[In] IntPtr lParam);
[return: MarshalAs(UnmanagedType.Bool)]
internal delegate bool EnumResTypeProc(
[In] IntPtr hModule,
[In] IntPtr lpszType,
[In] IntPtr lParam);مثال علي كيفية ايجاد انواع المصادر
// Win32.cs
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
public enum ResourceType : uint
{
Cursor = 1, // RT_CURSOR Hardware-dependent cursor resource.
Bitmap = 2, // Bitmap resource.
Icon = 3, // Hardware-dependent icon resource.
Menu = 4, // Menu resource.
Dialog = 5, // Dialog box.
String_Table = 6, // String-table entry.
FontDir = 7, // Font directory resource.
Font = 8, // Font resource.
Accelerator = 9, // Accelerator table.
RC_Data = 10, // Application-defined resource (raw data).
Message_Table = 11, // Message-table entry.
Group_Cursor = 12, // Hardware-independent cursor resource.
Group_Icon = 14, // Hardware-independent icon resource.
Version = 16, // Version resource.
DlgInclude = 17, // Allows a resource editing tool to associate a string with an .rc file.
PlugPlay = 19, // Plug and Play resource.
VXD = 20, // VXD.
Animated_Cursor = 21, // Animated cursor.
Animated_Icon = 22, // Animated icon.
Html = 23, // HTML.
Manifest = 24, // Microsoft Windows XP: Side-by-Side Assembly XML Manifest.
Dialog_Data = 240, //
ToolBar = 241 //
}
[Flags]
internal enum LoadLibraryFlags
{
DONT_RESOLVE_DLL_REFERENCES = 0x00000001,
LOAD_LIBRARY_AS_DATAFILE = 0x00000002,
LOAD_WITH_ALTERED_SEARCH_PATH = 0x00000008,
LOAD_IGNORE_CODE_AUTHZ_LEVEL = 0x00000010
}
public class Win32
{
#region API Imports
[return: MarshalAs(UnmanagedType.Bool)]
internal delegate bool EnumResTypeProc(
[In] IntPtr hModule,
[In] IntPtr lpszType,
[In] IntPtr lParam);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
internal extern static IntPtr LoadLibraryEx(
[In] [MarshalAs(UnmanagedType.LPTStr)]string lpFileName,
[In] IntPtr hFile,
[In] LoadLibraryFlags dwFlags);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal extern static bool FreeLibrary(
[In] IntPtr hModule);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal extern static bool EnumResourceTypes(
[In] IntPtr hModule,
[In] EnumResTypeProc lpEnumFunc,
[In] IntPtr lParam);
#endregion
#region Macro
// التأكد من نوعية اسم المصدر هل هو من نوع رقمي ام لا
public static bool IsIntResource(IntPtr value)
{
// return (((uint)val) >> 16) == 0;
return (((uint)value) <= ushort.MaxValue);
}
public static bool IsIntResource(string value)
{
ushort iResult;
return ushort.TryParse(value, out iResult);
}
public static IntPtr MakeIntResource(ushort wInteger)
{
return (IntPtr)wInteger;
}
public static int MakeIntResourceW(ushort wInteger)
{
return 0x0000FFFF & wInteger;
}
public static string GetResourceName(int val)
{
return ((ResourceType)val).ToString().Replace('_', ' ');
}
public static string GetResourceName(string val)
{
if(IsIntResource(val)) {
return GetResourceName(int.Parse(val));
}
return val;
}
// تحويل المؤشر الي نص
public static string PtrToString(IntPtr ptr)
{
return IsIntResource(ptr) ? ptr.ToString() : Marshal.PtrToStringUni(ptr);
}
// تحويل int الي مؤشر
public static IntPtr ToPtr(int val)
{
return (IntPtr)((uint)val);
}
// تحويل النص الي مؤشر
public static IntPtr ToPtr(string val)
{
if(IsIntResource(val)) {
return (IntPtr)uint.Parse(val);
} else {
return Marshal.StringToHGlobalAuto(val);
}
}
#endregion
}
// GetResType.cs
using System;
using System.Text;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
static class Program
{
[STAThread]
static void Main(string[] args)
{
IntPtr hLib = IntPtr.Zero;
if(args != null && args.Length> 0) {
hLib = Win32.LoadLibraryEx(args[0], IntPtr.Zero, LoadLibraryFlags.LOAD_LIBRARY_AS_DATAFILE);
Win32.EnumResourceTypes(hLib, new Win32.EnumResTypeProc(EnumResTypes), IntPtr.Zero);
}
if(hLib != IntPtr.Zero)
Win32.FreeLibrary(hLib);
}
static bool EnumResTypes(IntPtr hModule, IntPtr lpszType, IntPtr lParam)
{
if(hModule == IntPtr.Zero)
return false;
MessageBox.Show(Win32.GetResourceName(Win32.PtrToString(lpszType)));
return true;
}
}
الجزءالقادم ان شاءالله سأتكلم عن ايجاداسماءالمصادر من خلال انواعها