Confirmed users
656
edits
No edit summary |
No edit summary |
||
| Line 165: | Line 165: | ||
The followLinks attribute becomes ::GetFollowLinks and ::SetFollowLinks, and diskSpaceAvailable becomes ::GetDiskSpaceAvailable. Simple when you know, and used everywhere in the source. | The followLinks attribute becomes ::GetFollowLinks and ::SetFollowLinks, and diskSpaceAvailable becomes ::GetDiskSpaceAvailable. Simple when you know, and used everywhere in the source. | ||
=== nsI vs. ns === | |||
The interface is named '''nsILocalFile''' and the implementations are all named '''nsLocalFile*''', dropping the ''I''. This is another obvious thing once you know to look for it, but can be confusing when you start and your eye skims over '''nsIFoo''' and '''nsFoo''' as though they were the same thing. Incidentally, the ''ns'' prefix stands for Netscape, and you'll also sometimes encounter ''mozI'' and ''moz'' as a naming prefix. | |||
== Interface Implementations == | == Interface Implementations == | ||
| Line 188: | Line 192: | ||
83 #endif | 83 #endif | ||
The build system once again does the heavy lifting and figures out which implementation to use at compile time (see [http://hg.mozilla.org/mozilla-central/file/0cd41f599080/xpcom/io/Makefile.in Makefile.in]): | |||
91 ifeq ($(MOZ_WIDGET_TOOLKIT),os2) | 91 ifeq ($(MOZ_WIDGET_TOOLKIT),os2) | ||
| Line 222: | Line 208: | ||
103 endif # OS2 | 103 endif # OS2 | ||
=== | [http://hg.mozilla.org/mozilla-central/file/0cd41f599080/xpcom/io/nsLocalFileCommon.cpp nsLocalFileCommon.cpp] includes [http://hg.mozilla.org/mozilla-central/file/0cd41f599080/xpcom/io/nsLocalFile.h nsLocalFile.h], and therefore all the platform specific headers we added above. It implements some common elements of the interface, leaving specifics to platform-specific implementations. If we take Windows and [http://hg.mozilla.org/mozilla-central/file/0cd41f599080/xpcom/io/nsLocalFileWin.h nsLocalFileWin.h] as an example, we see where the NS_DECL_NSILOCALFILE macro gets used, and therefore where our interface gets declared: | ||
82 // nsILocalFile interface | |||
83 NS_DECL_NSILOCALFILE | |||
We also see how our interface methods and attributes get implemented for this platform. Here is the code for the '''followLinks''' attribute and '''launch''' method: | |||
<pre> | |||
2565 /* attribute PRBool followLinks; */ | |||
2566 NS_IMETHODIMP | |||
2567 nsLocalFile::GetFollowLinks(PRBool *aFollowLinks) | |||
2568 { | |||
2569 *aFollowLinks = mFollowSymlinks; | |||
2570 return NS_OK; | |||
2571 } | |||
2572 NS_IMETHODIMP | |||
2573 nsLocalFile::SetFollowLinks(PRBool aFollowLinks) | |||
2574 { | |||
2575 MakeDirty(); | |||
2576 mFollowSymlinks = aFollowLinks; | |||
2577 return NS_OK; | |||
2578 } | |||
... | |||
2678 NS_IMETHODIMP | |||
2679 nsLocalFile::Launch() | |||
2680 { | |||
2681 const nsString &path = mWorkingPath; | |||
2682 | |||
2683 // use the app registry name to launch a shell execute.... | |||
2684 LONG r = (LONG) ::ShellExecuteW(NULL, NULL, path.get(), NULL, NULL, | |||
2685 SW_SHOWNORMAL); | |||
2686 | |||
2687 // if the file has no association, we launch windows' "what do you want to do" dialog | |||
2688 if (r == SE_ERR_NOASSOC) { | |||
2689 nsAutoString shellArg; | |||
2690 shellArg.Assign(NS_LITERAL_STRING("shell32.dll,OpenAs_RunDLL ") + path); | |||
2691 r = (LONG) ::ShellExecuteW(NULL, NULL, L"RUNDLL32.EXE", shellArg.get(), | |||
2692 NULL, SW_SHOWNORMAL); | |||
2693 } | |||
2694 if (r < 32) { | |||
2695 switch (r) { | |||
2696 case 0: | |||
2697 case SE_ERR_OOM: | |||
2698 return NS_ERROR_OUT_OF_MEMORY; | |||
2699 case ERROR_FILE_NOT_FOUND: | |||
2700 return NS_ERROR_FILE_NOT_FOUND; | |||
2701 case ERROR_PATH_NOT_FOUND: | |||
2702 return NS_ERROR_FILE_UNRECOGNIZED_PATH; | |||
2703 case ERROR_BAD_FORMAT: | |||
2704 return NS_ERROR_FILE_CORRUPTED; | |||
2705 case SE_ERR_ACCESSDENIED: | |||
2706 return NS_ERROR_FILE_ACCESS_DENIED; | |||
2707 case SE_ERR_ASSOCINCOMPLETE: | |||
2708 case SE_ERR_NOASSOC: | |||
2709 return NS_ERROR_UNEXPECTED; | |||
2710 case SE_ERR_DDEBUSY: | |||
2711 case SE_ERR_DDEFAIL: | |||
2712 case SE_ERR_DDETIMEOUT: | |||
2713 return NS_ERROR_NOT_AVAILABLE; | |||
2714 case SE_ERR_DLLNOTFOUND: | |||
2715 return NS_ERROR_FAILURE; | |||
2716 case SE_ERR_SHARE: | |||
2717 return NS_ERROR_FILE_IS_LOCKED; | |||
2718 default: | |||
2719 return NS_ERROR_FILE_EXECUTION_FAILED; | |||
2720 } | |||
2721 } | |||
2722 return NS_OK; | |||
2723 } | |||
</pre> | |||
== Conclusion == | |||
We've followed the chain from our IDL to a C++ implementation specific to Windows, in the processing visiting: | |||
* nsILocalFile.idl | |||
* nsILocalFile.h | |||
* nsLocalFile.h | |||
* nsLocalFileWin.h | |||
* nsLocalFileCommon.cpp | |||
* nsLocalFileWin.cpp | |||
Understanding the difference between all these files, and knowing where to look for them, goes along way to helping you understand the code. | |||
For further information about how to use XPCOM interfaces like nsILocalFile, see [[Education/Learning/UsingXpcom|Using XPCOM Components in C++ and JavaScript]]. | |||