Closed tannerhelland closed 10 years ago
Re: Help docs, this is an area of interest for myself too as I wish to include help in MaSS1VE. My approach would be a side-pane in the MDI with a web-browser control, browsing web-based [HTML] documentation. Thus, one could share the same doc files on the website (good for your Google index) and in the app.
Having a side-pane on the MDI means that one can always refer to the help step-by-step at the same time as using the application, without having to alt-tab between windows. Others however may have large screens or two screens and will want to open the help in their browser, and with web-based docs that wouldn't be a problem.
One issue that would affect PD more than it does MaSS1VE is tool windows being in the way of the help pane or modal windows not allowing you to scroll the help pane. You could position the tool windows on the screen appropriately when the help pane is visible.
Do you know a good way to implement an in-app HTML viewer in VB?
I do not, so my first draft will probably just spawn pages in the user's browser, which they can then deal with as they please. I'll be wrapping all help calls in a dedicated function, so if I ever crack the issue of rendering webpages inside the app itself, then I could revisit displaying it in-program, with all the pitfalls that entails.
(edited to clean up email formatting)
I thought you would have known this already -- it's incredibly simple to embed an IE web view into VB6, Microsoft have provided an ActiveX control for decades. See http://www.vbforums.com/showthread.php?384076-Webbrowser-Control-Tip-and-Examples for some initial directions.
Oh I know about the ActiveX control, but I can't use it for PD. :( VB6 OCXs are not included by default in Vista/7/8 installs - see the support statement:
http://msdn.microsoft.com/en-us/vstudio/ms788708.aspx
You must distribute/install any OCXs yourself, which is why I don't use them in PD.
Note also that if you do decide to go the OCX route, they have a number of known issues with IE10 installs (one such thread: http://answers.microsoft.com/en-us/ie/forum/ie10-windows_7/common-controls-do-not-load-in-vb6-after-ie10/484d3294-162c-41d8-b349-1c90dff9b36b)
Oh yes, I hadn't thought about having to redistribute the OCX >.< That is a pain. I wonder if it would be possible to adapt this code to embed IE without using the OCX: http://www.codeproject.com/Articles/18417/Use-an-ActiveX-control-in-your-Win32-Project-witho But that would be a major project (embedding it would be alright -- interfacing with it in VB6 could be impossible)
If anyone was to go that route, I wonder if it would be easier to hack the IE scripting interface:
http://msdn.microsoft.com/en-us/library/ms970457.aspx
I use the scripting model for my Language Editor -> Google Translate interoperability, and it's quite nice to work with. (It also uses the fully supported and installed-by-default scrrun.dll)
As you mention, interfacing with the webpage is the big problem. The scripting language allows you to spawn an IE window, with parameters for things like the size of the window, but I have no idea if those parameters affects the default IE install - quite a lot of testing would be required to make sure the user's default IE experience wasn't affected!
OT: documentation for the IE scripting model:
Thanks for the links, I may consider tackling this in the future. I definitely want some kind of embedded help before I reach 1.0.
What would be REALLY nice would be a markdown/remarkable user control: pass it a string, and it renders an interactive window... (hint hint nudge nudge)
:D
Rendering plain text manually wouldn't be difficult, DrawText
could do it all in one call (it has multi-line support with word-wrapping) -- the huge issue is formatting, working out where one word ends and the next begins when changing text style, and then adding word-wrapping to that. And on top of that, how would I support system text-selection in a custom render like that? It's such a tricky problem I don't know if I would be up to the task.
We could use the RichText control, but the RTF format is rather nasty and not very portable (to other formats that is)
Ugh, I didn't think of text selection. Ugly ugly stuff. I am starting to see why so many applications simply spawn a help page in the default system browser.
Here's another idea. Not sure if you've heard of the vbRichClient project (basically a project to let VB6 interface with the cairo rendering library):
http://www.vbrichclient.com/#/en/Downloads.htm
Very interesting project, with some very impressive demos. It includes a preliminary webkit wrapper that's only ~3.5mb, with an associated widget for interactions. (Large for a dependency, I know - but tiny considering it's an embedded browser.)
The problem with vbRichClient is that the core DLL must be registered on the target system. I don't know if there is a way around this, but I have been investigating that project for other reasons, so when the time comes perhaps I'll open a dialog with Olaf. (We've met peripherally through vbforums, very nice guy and very talented coder.)
A lot of people have created rich text / HTML controls but there's just none with source that could be embedded and not that many that are free! I think I'll have to look into the CreateWindowEx
approach
I have discovered that it's very easy to create a web browser control!:
'Use an ActiveX container: http://support.microsoft.com/kb/192560
'BTW: atl.dll is shipped and supported in Vista/7/8, and probably XP
Private Declare Function AtlAxWinInit Lib "atl.dll" () As Long
Private Declare Function CreateWindowEx Lib "user32" Alias "CreateWindowExA" ( _
ByVal dwExStyle As Long, _
ByVal lpClassName As String, _
ByVal lpWindowName As String, _
ByVal dwStyle As Long, _
ByVal X As Long, _
ByVal Y As Long, _
ByVal nWidth As Long, _
ByVal nHeight As Long, _
ByVal hWndParent As Long, _
ByVal hMenu As Long, _
ByVal hInstance As Long, _
lpParam As Any _
) As Long
Private Sub Form_Load()
Call AtlAxWinInit
'Create the web browser instance: http://forum.vingrad.ru/faq/topic-159618.html
Call CreateWindowEx( _
0, "AtlAxWin", "http://localhost/forums", &H40000000 Or &H10000000 Or &H40000, _
25, 25, 640, 300, Me.hWnd, ByVal 0, App.hInstance, ByVal 0 _
)
End Sub
Now I just need to interface with the thing! We won't need much to use this as a help browser (just Navigate and Back / Forward calls). I think there's a lot more code examples out there of how to attach an IWebBrowser2 interface to a hwnd than there are examples of creating the ActiveX control container -- that took some serious sleuthing!
Note to self: Interfacing with this is actually super hard to work out. I've discovered through much Googling that we can use AtlAxGetControl
to return an IUnknown
interface, using a TypeLibrary that exposes this interface we can potentially get an Object reference from that to interface with the web browser in a late-binding fashion.
See the "Adding methods and properties at run-time with IDispatch" on this page http://www.mvps.org/emorcillo/en/code/vb6/index.shtml for details -- he very easily converts an IUnknown
into an Object and I will play with this to see if I can interface with the web browser control I've created.
This is crazy-hard stuff to work out! >_<
DONE IT!!!!!
Despite the 6-hour absolute headache of researching this, I have successfully late-bound to a web browser control (using only the hWnd) that I've made with CreateWindowEx
-- no OCX!! The only drawback is that you have to distribute olelib.tlb with your source code, but it won't be required by the exe.
It's a really, really small amount of code in the end, would you believe it!
Private Sub Form_Load()
Call AtlAxWinInit
Let IE_hWnd = CreateWindowEx( _
0, "AtlAxWin", "http://localhost/", &H40000000 Or &H10000000 Or &H40000, _
25, 25, 640, 300, Me.hWnd, ByVal 0, App.hInstance, ByVal 0 _
)
End Sub
Private Sub Command1_Click()
Dim IUnk As Long
Call AtlAxGetControl(IE_hWnd, IUnk)
Dim IE As Object
Set IE = GetObjectFromIUnknown(IUnk)
MsgBox IE.LocationName
Set IE = Nothing
End Sub
Public Function GetObjectFromIUnknown(ByVal ptrIUnknown As Long) As Object
Dim objUnk As OLELIB.IUnknown
Call CopyMemory(objUnk, ptrIUnknown, 4&)
Set GetObjectFromIUnknown = objUnk
Call CopyMemory(objUnk, 0&, 4&)
End Function
I'll probably work on turning what I've learned into a user control now. It won't get the browser events, but that shouldn't be necessary for a simple help browser.
Correction: TLB is not needed :)
Are you still looking to have help files for 6.2? I'm working on the help viewer control for MaSS1VE and if you give the go ahead I can focus on finishing up the control so you could use it for PhotoDemon. It works a the moment but lacks events and methods, which I've started to tackle.
Hoo boy, that's an excellent question. I think I've finally settled on a mechanism for creating the documentation itself: Dokuwiki (https://www.dokuwiki.org/dokuwiki). I got the idea from this article (http://archive.timmmmyboy.com/2013/11/writing-collaborative-documentation-with-dokuwiki-and-github/). Not sure if you've seen dokuwiki before, but it's basically the NNF of wikis! No database, all information stored as text files, autogeneration of ToC menus based on folder layouts - for me, I think it's a good solution, especially since I still use git to track diffs.
Anyway, aside from setting up a test implementation at photodemon.org/help, I've done very little actual documenting. Since I'm getting fairly close to having a 6.2 beta ready, and I have effectively zero documentation written, I'm going to say that an in-program help viewer is not going to happen in 6.2.
So no hurry on my part, but soon I'll start playing with the control as part of solving the contextual help problem for PD. Is the MaSS1VE Issues page the best place to post feedback?
Because 6.0 was such a feature-heavy release, I would like 6.2 to focus more on incremental improvements and back-end updates. I would also like a much shorter release window (5-6 weeks).
With 6.0 now in feature freeze, here is a list of the significant items I plan to investigate for 6.2. A few disclaimers:
That said, here's the current roadmap.
Floating/dockable toolboxes.Finished! See #98 for any remaining details.Right now, PD's two tool panels are picture boxes on the main MDI form. Not ideal. The should be converted to their own forms.Toolboxes must be dockable. I won't implement this otherwise, because faulty handling of this in other photo editors drives me insane. When the parent form is moved, all tool windows must be kept in a relative position.Color managed workflow.Finished! See #103 for details.I've spent a few months compiling notes and resources on this. Between the Windows API and FreeImage, it should theoretically be possible to provide a basic color-managed workflow.If nothing else, images with an embedded profile should at least use that to convert into the sRGB space prior to editing.Exporting ICC profiles is a tougher question - not sure the best approach there. I don't want a bunch of preferences required for this, but there's not really a "best" default behavior. Hence the need for investigation.Redesigned Undo handler.Finished! See ad38a42f4f5aa38e54af525e406262c227b9500cUndo handling is currently messy, with various aspects being handled by totally different modules. Each pdImage should contain a new pdUndo class, which maintains a list of all actions and their relevant state on disk.If done properly, this should make the next item possible...This would make an eventual transition to a tabbed interface much easier, and if I'm rewriting the viewport anyway (as part of layer support), this would be a good time to revisit.The new viewport handler should be destination agnostic. Pass it an arbitrary hDC and a source pdImage (or possibly source pdLayer...?) and it takes care of the rest. This is important to avoid redundant work for zoom/pan tool previews, below.Already done; all viewport calls require a destination canvas control now.How to handle scroll/zoom is an interesting question. I have concerns about making the viewport a user control, because it has merits as a standalone class, separate from any UI elements.I ended up making a viewport user control, despite my concerns, and I will shortly be moving the zoom control from the file toolbar to the viewport itself.Zoom/pan for tool previews.Finished!As a sub-item, potentially allow previewing on the main image, not just the tool window.Not feasible at present; perhaps in the future.A number of issues related to this have already been solved. For example, ratio between preview size and image size, which actions like blur need to correctly preview blur strength, is now handled by the preview image generator, so individual tools are already prepared for live changes.Now, the real work must be done in the prepImageData function, which must communicate with a given preview control to figure out what chunk of the image to preview.Note that selections greatly complicate this. For example, when a selection is active, it can be helpful to preview the full image (not just the selected area) to see how any changes will affect the surrounding area. However, the UI to do this is tough - we don't want a million buttons on the preview control, especially because there is no room for text so items will have to be icons.Previews when a selection is active have been reworked to show the fully composited selection + effect over the main image. I believe this is most useful for determining how to best apply a tool.Click-to-set-center point for relevant tools (distorts, vignetting, etc).Finished! See 56b0b9aaccb45337b9628e505fb8ccadc221f90b.The feasibility of this will be closely tied to zoom/pan support in tool preview windows.