⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch19.htm

📁 delphi自学的好教材!特别适合刚刚起步学习delphi的人员!同样对使用者具有参考价值!
💻 HTM
📖 第 1 页 / 共 5 页
字号:
owner. Finally, the form is shown.</P><P>All that remains is to reset the DLL's Application pointer before unloading theDLL. You can use a DLLProc to restore the DLL's application pointer:</P><P><PRE>procedure MyDLLProc(Reason: Integer);begin  if Reason = DLL_PROCESS_DETACH then    { DLL is unloading. Restore the Application pointer. }    if Assigned(DllApp) then      Application := DllApp;end;</PRE><P>Remember, you saved the DLL's Application pointer earlier, so now you just restoreit.</P><P>As you can see, placing an MDI child form in a DLL requires extra work, but itis certainly possible. The code for the book has an application project called MDIAppand a DLL project called MyForms. These two projects illustrate using an MDI formin a DLL.</P><P><H4>Showing a DLL Form from a Non-Delphi Application</H4><P>Calling a form from a non-VCL application requires a slightly different approach.What you have to do is create a standalone function in the DLL that is called bythe calling application. This function can be called from any program provided youdeclare the function with stdcall. Within the function body, you then create andexecute the form. The function looks like this:</P><P><PRE>function ShowForm : Integer; stdcall;</PRE><PRE>var</PRE><PRE>  Form : TMyForm;begin  Form := TMyForm.Create(Application);  Result := Form.ShowModal;  Form.Free;end;</PRE><P>Notice that Application is passed for the form's parent. This is the DLL's Applicationobject and serves as the owner of the form. Although I explicitly free the TMyFormobject, it isn't strictly necessary because the DLL's Application object will deletethe form if I neglect to.</P><P><H2><A NAME="Heading20"></A>Using Resources in DLLs</H2><P>Sometimes it's convenient to have resources contained in a DLL. I've already mentionedinternationalization and how a DLL can be used to make your program more easily portableto languages other than the one for which it was designed. Let's say you have aninstructions screen for your application and that those instructions are containedin five strings in a DLL. The strings might be named IDS_INSTRUCTION1, IDS_INSTRUCTION2,and so on. You could load and display the strings like this:</P><P><PRE>LoadString(DllInstance, IDS_INSTRUCTION1, Buff, SizeOf(Buff));InstructionLabel1.Caption := Buff;</PRE><P>The first parameter of the LoadString function contains the instance handle ofthe module where the strings can be found. The second parameter contains the ID numberof the resource to load. You could create DLLs that contain string resources in severaldifferent languages and simply load the appropriate DLL based on a user selection.The code might look like the following:</P><P><PRE>var  DLLName : String;begin  case Language of    laFrench : DllName := `french.dll';    laGerman : DllName := `german.dll';;    laSpanish : DllName := `spanish.dll';    laEnglish : DllName := `english.dll';  end;  DllInstance := LoadLibrary(PChar(dllName));end;</PRE><P>You only have to load the correct DLL; the rest of the code remains the same (assumingthe strings have the same identifiers in each of the DLLs, of course). This is justone example of using resources contained in a DLL. You will find many uses for thistechnique.</P><P><H3><A NAME="Heading21"></A>Creating a Resource DLL</H3><P>You can create a DLL that contains only resources, or you can mix code and resourcesin the same DLL. Placing resources in a DLL is much the same as adding resourcesto an application. To create a resource DLL, start a new DLL project and then adda line in the DLL to link the resources:</P><P><PRE>{$R RESOURC.RES}</PRE><P>That's all there is to creating a resource DLL. I discussed creating resourcefiles on Day 8, so I won't go over that ground again here.</P><P><H3><A NAME="Heading22"></A>Putting the Resource DLL to Work</H3><P>You must have the DLL's instance handle before you can access resources containedin the DLL. If your DLL contains resources only, you will load the DLL dynamically.If your DLL contains resources and code, you might choose to load the DLL statically.If you load the DLL statically, you will still have to call LoadLibrary to get theinstance handle:</P><P><PRE>DllInstance := LoadLibrary(`resource.dll');</PRE><P>Now you can use the instance handle wherever required. The following code loadsa bitmap resource contained in a DLL into an Image component:</P><P><PRE>procedure TMainForm.FormCreate(Sender: TObject);begin  DLLInstance := LoadLibrary(`resource.dll');  if DLLInstance &lt;&gt; 0 then begin    Image.Picture.Bitmap.      LoadFromResourceName(DLLInstance, `ID_BITMAP1');    FreeLibrary(DLLInstance);  end else    MessageDlg(`Error loading resource DLL.',      mtError, [mbOk], 0);end;</PRE><P>Actually, there's not much left to say. To review, though, you know that you canload resource DLLs either statically or dynamically. Either way you have to use LoadLibraryto get the instance handle of the DLL. Don't forget to call FreeLibrary when youare done with the DLL or before your application closes.</P><BLOCKQUOTE>	<P><HR><strong>NOTE:</strong> Using dynamic loading has the added advantage of allowing your application	to load faster. In many cases you load the resource DLL only when it's needed and	unload it when it's no longer needed. This results in your application using less	memory than when the resources are contained in the executable file. The downside	to static loading is that your users might see a slight pause when the resource DLL	loads. Try to anticipate as much as possible and load the resource DLL when it is	least likely to be noticed. <HR></BLOCKQUOTE><P>Remember JumpingJack from Day 8? The book's code has a version of JumpingJackthat loads the bitmap, sound, and string resources from a DLL. Check out that programfor an example of using resources in a DLL.</P><P><H2><A NAME="Heading23"></A>Summary</H2><P>Using dynamic link libraries isn't as difficult as it might first appear. DLLsare a great way to reuse code. After you create a DLL, you can call it from any applicationthat needs the functionality the code in that DLL provides. Placing VCL forms ina DLL and then calling those forms from a non-Delphi application is a powerful feature.This means that you can create forms that others can call from just about any typeof Windows application, whether it is an application written in OWL, MFC, straightC, Visual Basic, and so on. Using resources in DLLs is effective if you have a lotof resources in your application and you want to control when and where those resourcesare loaded.<PRE></PRE><H2><A NAME="Heading24"></A>Workshop</H2><P>The Workshop contains quiz questions to help you solidify your understanding ofthe material covered and exercises to provide you with experience in using what youhave learned. You can find the answers to the quiz questions in Appendix A, &quot;Answersto the Quiz Questions.&quot;</P><P><H3><A NAME="Heading25"></A>Q&amp;A</H3><DL>	<DT></DT>	<DD><B>Q I have a relatively small program, and I don't see the need to use DLLs.	Should I reevaluate my structure?</B>	<P>	<DT></DT>	<DD><B>A</B> Probably not. For small applications, DLLs are often not necessary.	Any time you have classes that can be reused, you might as well use a DLL, but don't	go out of your way to use DLLs in a small application.	<P>	<DT></DT>	<DD><B>Q I'm trying to use a function in a DLL, but I keep getting an error on the	function declaration. The error says, Unsatisfied forward or external declaration.	What am I doing wrong?</B>	<P>	<DT></DT>	<DD><B>A</B> You have forgotten the external keyword in your function declaration.	<P>	<DT></DT>	<DD><B>Q That GetProcAddress thing is a little weird. Do I have to use it to call	functions and procedures in my DLL?</B>	<P>	<DT></DT>	<DD><B>A</B> No. Just use static loading and you won't have to worry about the LoadLibrary,	GetProcAddress, and FreeLibrary functions.	<P>	<DT></DT>	<DD><B>Q My program compiles correctly, but at runtime I get an error that says The	procedure entry point XXX cannot be found in the dynamic link library XXX.DLL. What's	wrong?</B>	<P>	<DT></DT>	<DD><B>A</B> There are two possibilities that can lead to that error. First, you	might have accidentally misspelled or improperly capitalized a function name when	you declared the function in the calling application. Second, you might have forgotten	to place the function name in the exports section of the DLL.	<P>	<DT></DT>	<DD><B>Q I have a form contained in a DLL, and my calling application is a Delphi	program. The size of the DLL is pretty large. Is there any way I can reduce that?</B>	<P>	<DT></DT>	<DD><B>A</B> Unfortunately, no. This is where the power of programming in Delphi	works against you a little. Both the calling application and the DLL contain some	of the same VCL code. In other words, the code is being duplicated in both the .exe	and the .dll. You just have to live with the larger overall program size if you are	using forms in DLLs. You can eliminate this problem by using runtime packages. When	you use runtime packages, both the calling application and the DLL can use code in	the runtime packages.	<P>	<DT></DT>	<DD><B>Q I have a lot of wave files for my application. Right now they are contained	in separate files, but I would like to place them all in one file. Is a resource	DLL a good idea here?</B>	<P>	<DT></DT>	<DD><B>A</B> Absolutely. The only disadvantage is that if you need just one wave	file, you must load the entire DLL. Still, by using dynamic loading, you can load	and unload the DLL as required. The PlaySound function makes it easy to play sounds	from a DLL.	<P>	<DT></DT>	<DD><B>Q I live in a French-speaking country. Why should I bother with internationalization	of my program?</B>	<P>	<DT></DT>	<DD><B>A</B> It depends entirely on your target audience. If you know that your application	will be distributed only in countries where French is the native language, you don't	have to worry about internationalization. But if there is even the slightest possibility	that your program could be marketed in other countries, you should plan from the	beginning on international support. It's much easier to do it right the first time	than to go back and fix it later.	<P></DL><H3><A NAME="Heading26"></A>Quiz</H3><DL>	<DT></DT>	<DD><B>1. </B>How do you load a DLL using static loading?	<P>	<DT></DT>	<DD><B>2. </B>How do you load a DLL using dynamic loading?	<P>	<DT></DT>	<DD><B>3. </B>How do you call a function or procedure from a DLL that has been loaded	statically?	<P>	<DT></DT>	<DD><B>4. </B>What steps do you have to take to ensure that a function or procedure	in your DLL can be called from outside the DLL?	<P>	<DT></DT>	<DD><B>5. </B>In the case of a DLL that has been dynamically loaded, can you unload	the DLL at any time or only when the program closes?	<P>	<DT></DT>	<DD><B>6. </B>What must you do to display a Delphi form contained in a DLL from a	non-Delphi program?	<P>	<DT></DT>	<DD><B>7. </B>What is the name of the keyword used to declare functions and procedures	imported from a DLL?	<P>	<DT></DT>	<DD><B>8. </B>How do you add resources to a DLL?	<P>	<DT></DT>	<DD><B>9. </B>Does a resource DLL need to contain code as well as the resources?	<P>	<DT></DT>	<DD><B>10. </B>Can a DLL containing resources be loaded statically (when the program	loads)?	<P></DL><H3><A NAME="Heading27"></A>Exercises</H3><DL>	<DT></DT>	<DD><B>1. </B>Create a DLL that contains a procedure that displays a message box	when called.	<P>	<DT></DT>	<DD><B>2. </B>Create a calling application that will call the DLL in exercise 1.	<P>	<DT></DT>	<DD><B>3. </B>Create a DLL containing a form and a calling application that will	display the form.	<P>	<DT></DT>	<DD><B>4. </B>Create a DLL that has two bitmap resources.	<P>	<DT></DT>	<DD><B>5. </B>Create a program that will display on demand either bitmap resource	in your new DLL. (Hint: Use a TImage component and the LoadFromResourceId method.)	<P>	<DT></DT>	<DD><B>6. Extra Credit:</B> Write five DLLs, each of which contains the same strings	but in different languages.	<P>	<DT></DT>	<DD><B>7. Extra Credit:</B> Write a calling application that displays the strings	you created in exercise 6. Enable the user to choose the language to be used in the	application. Display the strings in the language chosen.</DL><H1></H1><CENTER><P><HR><A HREF="../ch18/ch18.htm"><IMG SRC="../button/previous.gif" WIDTH="128" HEIGHT="28"ALIGN="BOTTOM" ALT="Previous chapter" BORDER="0"></A><A HREF="../ch20/ch20.htm"><IMGSRC="../button/next.gif" WIDTH="128" HEIGHT="28" ALIGN="BOTTOM" ALT="Next chapter"BORDER="0"></A><A HREF="../index.htm"><IMG SRC="../button/contents.gif" WIDTH="128"HEIGHT="28" ALIGN="BOTTOM" ALT="Contents" BORDER="0"></A> <BR></P><P>&#169; <A HREF="../copy.htm">Copyright</A>, Macmillan Computer Publishing. Allrights reserved.</CENTER></BODY></HTML>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -