محمد علاء الدين

[ تمت الإجابة ]Global Window Class

6 ردود في هذا الموضوع

المكتبه msftedit.dll عندما يتم تحميلها تقوم بعمل تسجيل لـ window class بإسم RichEdit50W و التى هى احدث اصدار من الأداه RichEdit.

حاولت صنع مثال صغير يقوم بتسجيل Window class من خلال dll فتمت العمليه دون مشاكل و لكن عند استخدام اسم الـ Window class من داخل الـ Process الرئيسى لا يتعرف عليها.

داخل وائق الـ MSDN وجدت ان الـ window class حتى يتم التعامل معها من خلال الـ Process الرئيسى لابد و ان يكون الـ style الخاص بها يحتوى على CS_GLOBALCLASS و لكن و مع استخدمها لم يتم التعرف عليها.

التالى هو مثال الـ DLL


#include <windows.h>

HMODULE hCurModule;

LRESULT CALLBACK CtrlWndProc( HWND, UINT, WPARAM, LPARAM );

VOID RegisterGClass(HMODULE hModule);

BOOL APIENTRY DllMain( HMODULE hModule, DWORD fdwReason, LPVOID lpReserved )
{
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:

RegisterGClass(hModule);
break;

case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:

UnregisterClass(L"MyTextEdit", hModule);
break;
}

return TRUE;
}

LRESULT CALLBACK CtrlWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
switch(uMsg)
{
case WM_CREATE:
CreateCaret(hWnd,(HBITMAP)NULL, 1, 4);
break;

case WM_SETFOCUS:
ShowCaret(hWnd);
break;

case WM_KILLFOCUS:
DestroyCaret();
break;

default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
break;
};
}

VOID RegisterGClass(HMODULE hModule)
{
WNDCLASS wc;

wc.hInstance = hModule;
wc.lpszClassName = L"MyTextEdit";
wc.style = CS_DBLCLKS || CS_GLOBALCLASS;
wc.lpfnWndProc = CtrlWndProc;
wc.hCursor = (HCURSOR) LoadCursor(hModule,IDC_IBEAM);
wc.hbrBackground = (HBRUSH)COLOR_BTNFACE;

wc.cbClsExtra = NULL;
wc.cbWndExtra = NULL;
wc.hIcon = NULL;
wc.lpszMenuName = NULL;

hCurModule = hModule;

RegisterClass(&wc);
}

بالنسبه للبرنامج الذى يتم تحميل الـ dll من خلاله فهو مصنوع بالـ VB.Net و شكله كالتالى


Public Class myctl
Inherits Control

Private Declare Function LoadLibrary Lib "kernel32.dll" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As IntPtr

Protected Overrides ReadOnly Property CreateParams() As System.Windows.Forms.CreateParams
Get
Dim ptr As IntPtr = LoadLibrary("testCtl.dll")

Dim cp As CreateParams = MyBase.CreateParams

cp.ClassName = "MyTextEdit"

Return cp
End Get
End Property

End Class

و داخل الـ Form_Load استخدم الكود التالى لتجربة الـ WindowClass


Class Form1
Inherits Form

Overrides Sub OnLoad(ByVal e As EventArgs)
Dim c As New MyCtrl

Me.Controls.Add(C)
End Sub

End Class

عند تشغيل البرنامج يظهر استثناء و الرساله الخاصه به هى "Window class name is not valid."

و الله ولى التوفيق

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

ما بودي أفتي من راسي , كل شي يظهر لي تمام ^^

ما أظن إن هذا سبب المشكلة , لكن برأيي تسجيل الclass الأفضل يكون مرة واحده عند تحميل الdll للعملية , يعني في حدث ال DLL_PROCESS_ATTACH , رح أحاول أسوي dll بلغة purebasic وحاول تجربها عندك =\

الله يوفقك للي فيه الخير ,

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

قمت بعمل dllبنفس الكود عن طريق Purebasic و يظهر رسالة عند التحميل للعملية تحوي قيمة الatom of the class .



Procedure CtrlWndProc(hWnd.l,uMsg.l,wParam.l,lParam.l)
Select uMsg
Case #WM_CREATE
CreateCaret_(hWnd,#Null,1,4)
Case #WM_SETFOCUS
ShowCaret_(hWnd)
Case #WM_KILLFOCUS
DestroyCaret_()
Default
ProcedureReturn DefWindowProc_(hwnd,uMsg,wParam,lParam)
EndSelect
EndProcedure

Procedure RegisterGClass(hModule.l)
Define.WNDCLASS wc

wc\hInstance = hModule
wc\lpszClassName = @"MyTextEdit"
wc\style = #CS_DBLCLKS Or #CS_GLOBALCLASS
wc\lpfnWndProc = @CtrlWndProc()
wc\hCursor = LoadCursor_(hModule,#IDC_IBEAM)
wc\hbrBackground = #COLOR_BTNFACE
wc\cbClsExtra = #Null
wc\cbWndExtra = #Null
wc\hIcon = #Null
wc\lpszMenuName = #Null

MessageBox_(hModule,Str(RegisterClass_(@wc)),"testdll",0)

EndProcedure

ProcedureDLL AttachProcess(Instance)
EndProcedure

ProcedureDLL DetachProcess(Instance)
UnregisterClass_(@"MyTextEdit",Instance)
EndProcedure

RegisterGClass(Instance)

هذا أيضاَ تطبيق exe يقوم بتحميل المكتبة وعمل نافذة وإنشاء الclass السابق , الرسالة الأولى هي رسالة الdll والرسالة الثانية هي رسالة عنوان النافذة من التطبيق نفسه :


LoadLibrary_("testCtl.dll")
OpenWindow(0, 100, 200, 195, 260, "PureBasic Window", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget)
MessageBox_(0,Str( CreateWindowEx_(0,@"MyTextEdit",@"MyEdit",0,#CW_USEDEFAULT,#CW_USEDEFAULT,250,250,WindowID(0),#Null,GetModuleHandle_(0),#Null)),"App Test",0)
Repeat
Event = WaitWindowEvent()
If Event = #PB_Event_CloseWindow
Quit = 1
EndIf
Until Quit = 1

End

لا أدري لماذا لم يظهر العنصر الجديد , لست محترفاَ في التعامل مع CreateWindow ومثيلاتها :] لكن وجود مقبض يدل على إنشاء النافذة ,, على ما أظن .___.

سواء إستعملت #CS_GLOBALCLASS أو بدونها , أحصل على Handle للنافذة في البروسس الجديد =\ المشكلة لا يظهر أي كائن , لا أدري ما السبب !! الله يعينك =\ هذا كل ما أقدر عليه ^^

الملفات المترجمة بالمرفقات ,,,

دمت بود ,,

AT2000.rar

تم تعديل بواسطه Syntax_err
1

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

شكرا لكم

و الله ولى التوفيق

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

عند وضع كود تسجيل الـ window class داخل نفس process فإنها ستكون مرئيه فقط داخل هذا الـ process إن توافر فيها شرط واحد وهو وضع مقبض الـ module داخل hInstance.

لذا ليكون الحل عام : لعمل window class داخل module و استخدامها داخل process لابد من توافر عنصرين و هما :

1 - داخل الـ class style لابد من وجود CS_GLOBALCLASS بالإضافه لأى flags اخرى تريدها.

2 - العنصر hInstance لابدان يكون NULL لإنه ان احتوى على اى قيمه ستكون الـ window class خاصه بهذا الـ module فقط حتى و ان قمت بتطبيق الخطوه 1.

و الله ولى التوفيق

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
زوار
This topic is now closed to further replies.

  • يستعرض القسم حالياً   0 members

    لا يوجد أعضاء مسجلين يشاهدون هذه الصفحة .