I am finding using Git with their Windows client is so incredibly easy. I have committed new files to the repository.
https://github.com/PaulSquires/WinFBE
You will find a green button on that page called "Clone or download". Click that button and you will see an option to download the source in a zip file.
The latest code adds support for Localization. I have included the default "english.lang". To create a localization file for a particular language you simply need to copy the "english.lang" file to a new file, say, "french.lang" or "german.lang" and then go through the file changing the english text to the new language. Finally, in "Environment Options" select the new localization file and restart the editor.
I anticipate that I may have to increase the size of buttons and labels in order to handle the maximum size of some languages. I find that French is more verbose than English so controls will have to be a bit bigger.
All Latin languages are more verbose than English.
And German, with its very long compound nouns...
Mark Twain said the following about the length of German words:
“Some German words are so long that they have a perspective.â€
I have done a Spanish translation. Will have to check how it looks visually and to choose and adequate place for the keyboard shortcuts (&).
Wow, thanks Jose, that will be the first translation and should serve as a good test of this new localization stuff.
Cool :)
This is the translated file. It will need to be tweaked to make sure there are not two & symbols with the same letter in the menu.
Thanks Jose, now I can use your translated file to help make the controls a little larger. I think that I may have to fix the keyword casing combobox as well because I was testing for the selected English word rather than the combo index.
Next time you upload the code, remove AfxBstr, AfxStr, CImageCtx amd CUIlayout include files. These are simple tests. CImageCtx has not yeen be tested and CUILayout does not work as I like and was replaced by CLayout.
Some templates will also be changed to use the wrappers of AfxCtl.inc.
In the colors and fonts options there is an important feature missing, the charset. Setting the charset allows the user to write in its own language.
The supported charsets are:
' ========================================================================================
' Set the charsets
' ========================================================================================
FUNCTION FBSED_CharsetID (BYVAL strCharsetName AS STRING) AS LONG
SELECT CASE strCharsetName
CASE "Default" : FUNCTION = %SC_CHARSET_DEFAULT
CASE "Ansi" : FUNCTION = %SC_CHARSET_ANSI
CASE "Arabic" : FUNCTION = %SC_CHARSET_ARABIC
CASE "Baltic" : FUNCTION = %SC_CHARSET_BALTIC
CASE "Chinese Big 5" : FUNCTION = %SC_CHARSET_CHINESEBIG5
CASE "East Europe" : FUNCTION = %SC_CHARSET_EASTEUROPE
CASE "GB 2312" : FUNCTION = %SC_CHARSET_GB2312
CASE "Greek" : FUNCTION = %SC_CHARSET_GREEK
CASE "Hangul" : FUNCTION = %SC_CHARSET_HANGUL
CASE "Hebrew" : FUNCTION = %SC_CHARSET_HEBREW
CASE "Johab" : FUNCTION = %SC_CHARSET_JOHAB
CASE "Mac" : FUNCTION = %SC_CHARSET_MAC
CASE "OEM" : FUNCTION = %SC_CHARSET_OEM
CASE "Russian" : FUNCTION = %SC_CHARSET_RUSSIAN
CASE "Shiftjis" : FUNCTION = %SC_CHARSET_SHIFTJIS
CASE "Symbol" : FUNCTION = %SC_CHARSET_SYMBOL
CASE "Thai" : FUNCTION = %SC_CHARSET_THAI
CASE "Turkish" : FUNCTION = %SC_CHARSET_TURKISH
CASE "Vietnamese" : FUNCTION = %SC_CHARSET_VIETNAMESE
END SELECT
END FUNCTION
' ========================================================================================
and you set it sending the SCI_STYLESETCHARACTERSET message and STYLE_DEFAULT.
Thanks Jose, I have deleted those files. I have also updated new code to increase the size of dialogs and controls to help accommodate longer phrases in languages other than English. It is still not perfect but I don't want to make the controls overly large.
Ah, yes, I will add the charset stuff tonight, thanks!
The latest version GPF's when I compile an run it.
Also, you don't need to call AfxSetProcessDPIAware if you're using a manifest that already has <dpiAware>true</dpiAware>. I use it in the examples for testing purposes because many of them don't use a manifest.
In frmMain_Show you're using now your own message pump, but I', not seeing
ShowWindow pWindow->hWindow, nCmdShow
UpdateWindow pWindow->hWindow
before entering the message loop.
Quote from: Jose Roca on June 27, 2016, 07:54:17 PM
In frmMain_Show you're using now your own message pump, but I', not seeing
ShowWindow pWindow->hWindow, nCmdShow
UpdateWindow pWindow->hWindow
before entering the message loop.
I didn't use ShowWindow because I was setting the visibility using the call to:
SetWindowPlacement(pWindow->hWindow, @WinPla)
I will remove the AfxSetProcessDPIAware call.
I am just about to upload new code that has the font character set code.
I know where that gpf is. You will need to delete your ini file when you use the new code. There was also a potential gpf on program end due to me using "Delete" on the document array elements.
In clsConfig.LoadFromFile you are passing default.lang as the name of the language file, but default.lang does not exist.
Then you are calling LoadLocalizationFile( Exepath & "\" & this.LocalizationFile ) and returning FUNCTION = 0, when it should be:
FUNCTION = LoadLocalizationFile( Exepath & "\" & this.LocalizationFile )
and in WinMain you should check the success or failure of loading the localization file.
' Load configuration file
IF gConfig.LoadFromFile() = FALSE THEN RETURN FALSE
It is GPFing because loading the localization file is failing and then the program is trying to access a non dimensioned array.
The new code should be in Git now. Please let me know if experience any issues. :)
Quote from: Jose Roca on June 27, 2016, 08:26:38 PM
In clsConfig.LoadFromFile you are passing default.lang as the name of the language file, but default.lang does not exist.
Then you are calling LoadLocalizationFile( Exepath & "\" & this.LocalizationFile ) and returning FUNCTION = 0, when it should be:
FUNCTION = LoadLocalizationFile( Exepath & "\" & this.LocalizationFile )
and in WinMain you should check the success or failure of loading the localization file.
' Load configuration file
IF gConfig.LoadFromFile() = FALSE THEN RETURN FALSE
It is GPFing because loading the localization file is failing and then the program is trying to access a non dimensioned array.
I think you might be using old code? I am pretty sure that I changed the default value for the this.LocalizationFile equal to "english.lang".
I will double check the returning TRUE logic and add it based on your suggestion. Thanks Jose
I am changing a little bit of code related to the selection of the localization file. I am also going to add an error message should the language files be missing and then abort loading the application.
Okay Jose, the new code is on GitHub now. I moved the loading of the language file to WinMain and am aborting the application should the language file not be found or loads incorrectly.
Modified español.lang file.
In UpdateMRUMenu you're using WStr("(Empty)") instead of L(11,"(Empty)").
Thanks Jose, I have fixed the "Empty" problem and added the updated Spanish file. I have also corrected a problem in the UpdateMRUList code where I was not converting the "{CURDRIVE}" parameter to the current drive letter before comparing filenames in the current MRU list to see if it already existed.
All code is now in GitHub.
AndAlso is not highlighted as a keyword.
Quote from: Jose Roca on June 27, 2016, 10:44:46 PM
AndAlso is not highlighted as a keyword.
Yes, there are a few keywords like that. OrElse is another one.
I am hoping to add a new option to the Environment Options window to allow the user to easily type in the FB keywords (rather than having to manually edit the text file).
I will start updating the keyword list as I notice them. I should have already updated the AndAlso, OrElse ones but simply forgot to do so. :)
Modified the Spanish language file to fit the Find dialog controls.
Quote from: Jose Roca on June 27, 2016, 10:54:39 PM
Modified the Spanish language file to fit the Find dialog controls.
Awesome! I was hoping that there existed shorter words! :)
Well, "Find next" translates as "Buscar siguiente" or "Buscar siguiente ocurrencia", but it is too long for a button.
I made the first translation without knowing where it was going to be used. In the context of the find dialog, "Siguiente" fits the size of the button and its understandable.
Question: Do you ever sleep? :)
Isn't it like almost 4:00 AM in Spain right about now.
Like the Count Dracula, I go to sleep at dawn.
Hahaha, awesome. :)
I am off to bed soon. It is about 11:30 PM here. I have to crawl myself into work in the morning. Hope to get more coding done tomorrow.
The Find and Find Replace dialogs don't allow to paste text in the edit part of the combobox.
Just adding this code to the end of the CreateContextMenu function you get a context menu with icons.
DIM hInst AS HINSTANCE = GetModuleHandle(NULL)
AfxAddIconToMenuItem(hPopupMenu, 0, TRUE, AfxGdipIconFromRes(hInst, "IMAGE_UNDO"))
AfxAddIconToMenuItem(hPopupMenu, 1, TRUE, AfxGdipIconFromRes(hInst, "IMAGE_REDO"))
AfxAddIconToMenuItem(hPopupMenu, 3, TRUE, AfxGdipIconFromRes(hInst, "IMAGE_CUT"))
AfxAddIconToMenuItem(hPopupMenu, 4, TRUE, AfxGdipIconFromRes(hInst, "IMAGE_COPY"))
AfxAddIconToMenuItem(hPopupMenu, 5, TRUE, AfxGdipIconFromRes(hInst, "IMAGE_PASTE"))
AfxAddIconToMenuItem(hPopupMenu, 7, TRUE, AfxGdipIconFromRes(hInst, "IMAGE_INDENT"))
AfxAddIconToMenuItem(hPopupMenu, 8, TRUE, AfxGdipIconFromRes(hInst, "IMAGE_INDENT_REMOVE"))
AfxAddIconToMenuItem(hPopupMenu, 10, TRUE, AfxGdipIconFromRes(hInst, "IMAGE_COMMENT"))
AfxAddIconToMenuItem(hPopupMenu, 11, TRUE, AfxGdipIconFromRes(hInst, "IMAGE_COMMENT_REMOVE"))
It has never been so easy.
Those icons look good in your screenshot but on my system they do not. They are very undefined and washed out. I believe I made a similar post a couple of weeks ago about icons in the top menus. I can't post a screenshot right now but I will as soon as I am able. Are you able to test at 96 dpi to see how the icons scale on your system?
Also, I am using Windows 10 at home and Windows 7 at work. I get the same "blurriness" on both systems.
Quote from: Jose Roca on June 28, 2016, 12:21:54 AM
The Find and Find Replace dialogs don't allow to paste text in the edit part of the combobox.
That's odd. I am able to paste text into the edit portion of the comboboxes.
I can paste if I use the context menu of the control, but if I press Ctrl-V, the control loses the focus and the text is pasted in the document.
Regarding the icons, it must be that they aren't appropriate for the menus. There are some requirements that perhaps they don't satisfy. I have made a test with other icons at 96 DPI and they look fine (see capture).
Quote from: Jose Roca on June 28, 2016, 11:10:26 AM
I can paste if I use the context menu of the control, but if I press Ctrl-V, the control loses the focus and the text is pasted in the document.
Ah, okay. You are correct the paste seems to happen in the active document instead. The Ctrl+V accelerator key must be taking precedence. I never noticed it because I always use Shift+Insert for pasting.
Quote from: TechSupport on June 28, 2016, 12:10:44 PM
Quote from: Jose Roca on June 28, 2016, 11:10:26 AM
I can paste if I use the context menu of the control, but if I press Ctrl-V, the control loses the focus and the text is pasted in the document.
Ah, okay. You are correct the paste seems to happen in the active document instead. The Ctrl+V accelerator key must be taking precedence. I never noticed it because I always use Shift+Insert for pasting.
Looks like I might have to do something like this:
'' EDIT MENU
Case IDM_UNDO: Function = SendMessageW( GetFocus(), Iif(GetFocus()=hEdit, SCI_UNDO, WM_UNDO), 0, 0)
Case IDM_REDO: Function = SendMessageW( hEdit, SCI_REDO, 0, 0)
Case IDM_CUT: Function = SendMessageW( GetFocus(), Iif(GetFocus()=hEdit, SCI_CUT, WM_CUT), 0, 0)
Case IDM_COPY: Function = SendMessageW( GetFocus(), Iif(GetFocus()=hEdit, SCI_COPY, WM_COPY), 0, 0)
Case IDM_PASTE: Function = SendMessageW( GetFocus(), Iif(GetFocus()=hEdit, SCI_PASTE, WM_PASTE), 0, 0)
There is an easier way. Just remove
pWindow->AddAccelerator( FVIRTKEY Or FCONTROL, VK_Z, IDM_UNDO )
pWindow->AddAccelerator( FVIRTKEY Or FCONTROL, VK_X, IDM_CUT )
pWindow->AddAccelerator( FVIRTKEY Or FCONTROL, VK_C, IDM_COPY )
pWindow->AddAccelerator( FVIRTKEY Or FCONTROL, VK_V, IDM_PASTE )
These are standard Windows shortcuts and don't need an accelerator.
Thanks Jose, I have now removed those accelerators.
I have uploaded all the changes that I have made today. I am just starting to add Project Management stuff so don't pay too much attention to that yet.
You will have to modify the Spanish language file for the last 5 or 6 entries.
I added a new option in "Environment Options" to allow the direct adding/editing of FreeBASIC keywords. Those changes take affect immediately for all open Scintilla windows.
I also added the Command Line dialog.
New Spanish language file.
Code to add drag and drop files.
In OnCreate, add:
' // Enable drag and drop files
DragAcceptFiles hwnd, CTRUE
In OnDestroy, add:
' // Disable drag and drop files
DragAcceptFiles hwnd, FALSE
In frmMain_WndProc, add:
CASE WM_DROPFILES
' // Get the number of dropped files
DIM hDrop AS HDROP = cast(HDROP, wParam)
DIM nCount AS LONG = DragQueryFile(hDrop, &HFFFFFFFF, NULL, 0)
IF nCount = 0 THEN EXIT FUNCTION
DIM i AS LONG, nLen AS LONG, wszPath AS WSTRING * MAX_PATH
FOR i = 0 TO nCount - 1
nLen = DragQueryFile(hDrop, i, @wszPath, MAX_PATH)
' // Make sure it's a file, not a folder
DIM fd AS WIN32_FIND_DATAW
DIM hFind AS HANDLE = FindFirstFileW(@wszPath, @fd)
IF hFind <> INVALID_HANDLE_VALUE THEN
FindClose hFind
IF (fd.dwFileAttributes AND FILE_ATTRIBUTE_DIRECTORY) <> FILE_ATTRIBUTE_DIRECTORY THEN
' Create the new Scintilla window and load the file
DIM idx AS LONG
Dim pDoc As clsDocument Ptr = New clsDocument
pDoc->CreateCodeWindow(HWnd, False, False, @wszPath)
gpApp->AddDocument(pDoc) ' Add the new document to the global app
idx = gTTabCtl.AddTab( pDoc ) ' Add the new document to the top tabcontrol
gTTabCtl.SetFocusTab(idx)
END IF
END IF
NEXT
DragFinish hDrop
EXIT FUNCTION
You must modify this part, that is not working well:
' Create the new Scintilla window and load the file
DIM idx AS LONG
Dim pDoc As clsDocument Ptr = New clsDocument
pDoc->CreateCodeWindow(HWnd, False, False, @wszPath)
gpApp->AddDocument(pDoc) ' Add the new document to the global app
idx = gTTabCtl.AddTab( pDoc ) ' Add the new document to the top tabcontrol
gTTabCtl.SetFocusTab(idx)
The first time that I drop a file from explorer, nothing is displayed. The second time, both the first file dropped and the second are loaded and displayed.
You also need to check if the file is already loaded in the editor to no get the same file loaded twice.
That's great code Jose - thanks! I have implemented it and just uploaded it to github. It seems to be working perfectly. To load the file I simply loaded them through OnCommand_OpenIncludeFile.
If hFind <> INVALID_HANDLE_VALUE Then
FindClose hFind
If (fd.dwFileAttributes And FILE_ATTRIBUTE_DIRECTORY) <> FILE_ATTRIBUTE_DIRECTORY Then
gpApp->IncludeFilename = wszPath
OnCommand_OpenIncludeFile(HWnd)
End If
End If
In clsApp.ProjectAddFile, the compiler complains about this line:
FF_ListView_InsertItem( hLV, 0, 0, wzFile, pDoc )
changed to:
FF_ListView_InsertItem( hLV, 0, 0, wzFile, cast(long, pDoc) )
In frmProjectManager_Show, the compiler complains about function result not set.
You always leave
pWindow->DPI = 96 ' eg. 144 or any other value (96 is default)
Maybe you should include the .exe in the .zip file.
Thanks Jose - I have fixed those problems and uploaded the exe as well. I only started working on the project management stuff today so it is hardly functional at all. I expect to have much more of it completed tomorrow. I am trying to keep it simple. I also need to write the Project Options dialog where the user can specify things like choosing to compile to EXE, DLL or static lib; specify error compiler switches, debug switch, codegen switch, etc...
For every file added to a project you will be able to designate it as either (1) main file, (2) module, or (3) normal. Obviously there can only be one main file. If it is a module then it is compile to a standalone obj file and linked to the main file. If it is a normal file then it does nothing special. It our PowerBasic world we would use normal files and #INCLUDE them into the main file. In FreeBasic, you can compile files into object files and link them. By checking the filedate times against the source file you can possibly speed up compilation by not having to compile all files in a project.
Still lots of work to do in the project area.