• Welcome to Jose's Read Only Forum 2023.

CSED - Modification

Started by Gary Beene, October 17, 2013, 02:31:56 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

José Roca

One of the benefits to me personally, of doing a mod to CSED,  was to see first-hand how you write code.

This application is a little special. As I wrote it to test my CWindow class and wrappers, and the beta compilers (first version 9 and later version 10) with non trivial code, it makes use of many of the features implemented in these compilers, such classes, collections, queues, linked lists, string builder. First it was only ANSI, and during the beta testing of version 10, I added #IF DEFs to test that it worked fime both compiling it as ANSI or UNICODE. There are some left overs, like:

   '      vPath = pSed.TabFilePaths.Next
         pTabFilePaths = pSed.TabFilePaths
         vPath = pTabFilePaths.Next

The reason is that vPath = pSed.TabFilePaths.Next did not worked at that time because of a compiler's bug using the compound syntax and had to use an intermediate step. Later, probably I forgot to change it.

A remark saying that "we can't use the class name because all the CWindow main windows share the same class name." is no longer true, because I added an optional method to CWindow to specify the class name before you call the CreateWindow method.

I wrote CWindow to simplify SDK GUI creation, as the most often used objection against SDK was the many lines of code needed to fill the members of the WNDCLASSEX structure and register the class, the message pump and the many parameters of CreateWindowEx.

With CWindow, all that verbosity is reduced to:

pWindow.CreateWindow(%NULL, "CWindow with a button", 10, 10, 500, 320, 0, 0, CODEPTR(WindowProc))
pWindow.AddButton(pWindow.hwnd, %IDCANCEL, "&Close", 350, 250, 75, 23)

And subclassing of a control is as easy as adding the address of the subclass procedure:

pWindow.AddButton(pWindow.hwnd, %IDCANCEL, "&Close", 350, 250, 75, 23, 0, 0, CODEPTR(TextBtn_SubclassProc))

' ========================================================================================
' Processes messages for the subclassed Button window.
' ========================================================================================
FUNCTION TextBtn_SubclassProc ( _
   BYVAL hwnd   AS DWORD, _                 ' // Control window handle
   BYVAL uMsg   AS DWORD, _                 ' // Type of message
   BYVAL wParam AS DWORD, _                 ' // First message parameter
   BYVAL lParam AS LONG _                   ' // Second message parameter
   ) AS LONG

   ' // REQUIRED: Get the address of the original window procedure
   pOldWndProc = GetProp(hwnd, "OLDWNDPROC")

         ' // REQUIRED: Remove control subclassing
         SetWindowLong hwnd, %GWL_WNDPROC, RemoveProp(hwnd, "OLDWNDPROC")

   FUNCTION = CallWindowProc(pOldWndProc, hwnd, uMsg, wParam, lParam)

' ========================================================================================

When I did buy an high resolution monitor, I also added High DPI awareness to CWindow. The difference in sharpness is noticeable.

Gary Beene

Thanks very much for the additional information.

Before your explanation I did not realize that all non-empty command line content is sent to WM_CopyData, regardless of whether the app is starting or whether a 2nd instance of the app is attempting to start (that is, when 2nd instances are not allowed).

In the case of an app startup, the initialization stuff occurs, then you POST WM_User+1000, which in turn calls ProcessCommandLine which in turn sends command line data to WM_CopyData for actual opening/adding of the file specified in the command line.

And in the case of a 2nd instance, startup/POST is skipped and you go straight to ProcessCommandLine which in turn sends command line data to WM_CopyData for opening/adding of the file specified in the command line.

That's a very interesting sequence, one that I had a time following until you gave your additional comments.  But helped by your comments, I've been able to write the code to double-click and load a project file, even if CSED is already open.

Gary Beene

Just wandering around your CSED code some ....

In the Method FindOrReplace, when the dialog is already opened and the user hits Ctl-F again, you require that the user cancel the previous Find dialog.

You might, for example, have just kept the dialog open and replaced the search text with whatever the user now has highlighted.  Or, you might have had an Ok/Cancel on the popup MsgBox.  Or, you might just have automatically cancelled it yourself.

Can you comment on the thought process of taking the approach you did?

José Roca

The class stores the last search in the instance variable m_szLastFind to allow to do a next find (pressing the F3 key) or a backwards find (Shift+F3) without using the Find dialog. Obviously, if a second instance is allowed, the content of that variable will change, making useless to have the first instance of the dialog active.

Gary Beene

Hey Jose!
I wasn't so much thinking about having a 2nd Find dialog, as I was wondering why you didn't just automatically delete the first?

I guess that brings up the question. If I wanted to automatically close the first Find dialog and let a new one be created, how would I go about it?

José Roca

I'm using the Find/Replace dialog provided by Windows, not a custom dialog. It involves the registering of a custom message and special processing in the the message pump. The only safe way would be to find the handle of the Find dialog (you can't use the caption, because it is localized) and send a WM_CLOSE to it (or maybe to retrieve the identifier of the Cancel button and send a message to simulate a button click). Then send a WM_COMMAND message to the main window callback with the %IDM_FIND or %IDM_REPLACE identifier.

I think that is much simpler just to press the ESC key, but to each his own.

Gary Beene

In my modifications to CSED, I've somehow caused the top and bottom toolbar to force all buttons to the same width - much wider than the image that they contain.  I've made no changes to the CSED_TOOLBARS.inc file.

( toolbar buttons same size, too big )

I've searched through all the CSED source files, looking for where "toolbar" was used, but found nothing that I recognized as having the ability to force all toolbar buttons the same size.

Can you suggest where in your code I might have unknowingly resized the toolbar buttons?

José Roca


   hToolBar = pWindow.AddToolBar(pWindow.hwnd, %IDC_TOOLBAR, "", 0, 0, 0, 0, _


   hToolBar = pWindow.AddToolBar(pWindow.hwnd, %IDC_TOOLBAR, "", 0, 0, 0, 0, _

Gary Beene

I went back to the download file I got from you, CSED103_Source.rar.  I unpacked that and compiled the CSED.BAS.  The resulting EXE has the wide buttons.  But the EXE you put in your CSED103.Release.rar file has the narrow buttons.

So, I gather the change you just now posted must have been an update sometime between the source and release file uploads?

I tried the change you sent and that does the trick.  Because the release EXE didn't have the narrow buttons, I was assuming that my code mods had caused the change.  I'm always happy when it's not something I did!


Gary Beene

And, for the bottom toolbar I made the similar change of code like this ...
   hBottomToolBar = pWindow.AddToolBar(pWindow.hwnd, %IDC_BOTTOMTOOLBAR, "", 0, 0, 0, 0, _
              %WS_Child Or %WS_Visible Or %CCS_NoResize Or %TbStyle_Tooltips Or %TbStyle_Flat Or _
              %TbStyle_List Or %TbStyle_Transparent)
to this ...
   hBottomToolBar = pWindow.AddToolBar(pWindow.hwnd, %IDC_BOTTOMTOOLBAR, "", 0, 0, 0, 0, _
              %WS_Child Or %WS_Visible Or %CCS_NoResize Or %TbStyle_Tooltips Or %TbStyle_Flat)     'BEENE

Gary Beene

Jon Eskdale send me his fix to this ...
Quote... automatically close the first Find dialog and let a new one be created
which is this line ...
      If m_fr.lCustData <> 0 Then SendMessage m_hFind, %WM_Close, 0, 0

José Roca

I had forgotten that the handle of the Find window was already available.

Gary Beene

Hey Paul,
Yep, I like that idea ...
Quote.. getting the word at the current cursor position