import IDE;
import editor;
declare kbd = IDE.KeyboardManager.GetKeyboard("Editor");
// Choose a key combination
kbd.Assign("<Alt-F11>","get_h();");
kbd.Assign("<Alt-F12>","get_cpp();");
ChooseFile(ext)
{
declare buffersArray = new array [];
declare i = 0;
declare firstBuffer = editor.TopBuffer;
if( firstBuffer == NULL || !initialized(firstBuffer) ){
print "First Buffer invalid";
return;
}
declare current = firstBuffer;
do {
if( current.TopView != NULL){
declare currExt = new String(current.Extension);
currExt.Upper();
if( currExt.Text == ext.Text ){
buffersArray[i] = current.FullName;
i++;
}
}
current = current.NextBuffer(false);
} while( firstBuffer.FullName != current.FullName );
if( i == 0 ){
print "No modules";
return;
}
declare popup = new PopupMenu(200, 100, buffersArray);
declare res = popup.Track();
if( res == "" ) return;
current = firstBuffer;
for( declare j=0 ; ; current = current.NextBuffer(false),j++ ){
if( current.FullName == res ){
current.TopView.Window.IsHidden = false;
current.TopView.Window.Activate();
break;
}
}
}
get_cpp()
{
declare ext = new String(".CPP");
ChooseFile(ext);
}
get_h()
{
declare ext = new String(".H");
ChooseFile(ext);
}
Download ShowHCpp.zip
print ("SaveOnCompile.spp");
import IDE;
import debugger;
on IDE:>BuildStarted()
{
print ("Saving all...");
IDE.FileSaveAll();
pass();
}
on IDE:>MakeStarted()
{
print ("Saving all...");
IDE.FileSaveAll();
pass();
}
on debugger:>DebugeeAboutToRun()
{
print ("Saving all...");
IDE.FileSaveAll();
pass();
}
Download SaveOnCompile.zip
print("myedsize.spp");
import editor;
// import the DLL function
import "myedsize.dll" {
void PositionWindow(char*, int, int, bool);
}
// I like 600 pixels by 350 for my edit windows
declare width = 800;
declare height = 500;
declare ViewID;
on editor:>ViewCreated(newView)
{
ViewID = newView.Identifier;
pass(newView);
}
// if a view was activated and it was not
// an existing window then call the DLL
// function to move it
on editor:>ViewActivated(view)
{
if (ViewID == view.Identifier) {
pass(view);
declare newViewTitle = editor.TopView.Window.Title;
PositionWindow(newViewTitle, width, height, false);
ViewID = NULL;
}
pass(view);
}
///////////////////////////////////////////////////////////////
myedsize.cpp
#define WIN32_LEAN_AND_MEAN
#define STRICT
#include <windows.h>
#include <cstring.h>
#include <dir.h>
#include <stdio.h>
int xPos;
int yPos;
HWND hWndNew;
HWND hWndExisting;
HWND hWndMDI;
enum FileGroup {
Header,
Source,
Other
};
#define PAIRS_NUM 3
static const char* HeaderSourcePairsExt [][PAIRS_NUM] = {
{".h", ".cpp"},
{".hxx", ".cxx"},
{".rh",".rc"},
};
FileGroup GetFileGroup(const char* pszExt)
{
for (int i = 0; i < PAIRS_NUM; i++)
if (!strcmpi(pszExt, HeaderSourcePairsExt[i][Header]))
return Header;
else
if (!strcmpi(pszExt, HeaderSourcePairsExt[i][Source]))
return Source;
return Other;
}
const char* GetCorrespondingExt(FileGroup fileGroup, const char* pszExt)
{
for (int i = 0; i<PAIRS_NUM; i++)
if (!strcmpi(pszExt,HeaderSourcePairsExt[i][fileGroup]))
return HeaderSourcePairsExt[i][(fileGroup+1)%2];
return 0;
}
int GetOffset()
{
return GetSystemMetrics(SM_CYCAPTION) +(GetSystemMetrics(SM_CYFRAME) * 2);
}
string GetPath(const char* pszWndCaption)
{
string sCaption(pszWndCaption);
int nPos = sCaption.find_last_of(string(":"));
if (nPos != NPOS && nPos != 1)//C:\.....
sCaption.remove(nPos);
nPos = sCaption.find_first_of(string(" "));
if (nPos != NPOS)
sCaption.remove(nPos);
return sCaption;
}
string GetNameExt(const char* pszWndTitle, char* pszName, char* pszExt)
{
string sPath = GetPath(pszWndTitle);
fnsplit(sPath.c_str(),0,0,pszName,pszExt);
return string(pszName) + pszExt;
}
string GetNameExt(const char* pszWndTitle)
{
char pszName[MAXFILE];
char pszExt[MAXEXT];
return GetNameExt(pszWndTitle,pszName,pszExt);
}
BOOL CALLBACK FindExistingWindow(HWND hwnd, LPARAM pszNameExt)
{
const int size = 20;
char className[size];
GetClassName(hwnd, className, size);
if (hwnd == hWndNew || strcmp(className, "BCW5Editor"))
return TRUE;
if (IsIconic(hwnd))
return TRUE;
const int nCurrWndTitleLen = MAXPATH + 3;//title:2
char pszCurrWndTitle[nCurrWndTitleLen];
GetWindowText(hwnd,pszCurrWndTitle,nCurrWndTitleLen);
string sCurrNameExt = GetNameExt(pszCurrWndTitle);
if (sCurrNameExt == (char*)pszNameExt) {
hWndExisting = hwnd;
return FALSE;
}
return TRUE;
}
// callback function called to enumerate
// the child windows
BOOL CALLBACK EnumProc(HWND hwnd, LPARAM lParam)
{
const int size = 20;
char className[size];
GetClassName(hwnd, className, size);
if (hwnd == hWndNew || strcmp(className, "BCW5Editor")) return TRUE;
if (IsIconic(hwnd))
return TRUE;
RECT rect;
POINT point;
int offset = GetOffset();
GetWindowRect(hwnd, &rect);
point.x = rect.left;
point.y = rect.top;
ScreenToClient((HWND)lParam, &point);
if (point.y >= yPos)
yPos = point.y + offset;
return TRUE;
}
extern "C"
void PASCAL _export
PositionWindow(char* title, int width, int height, bool bSourceInLeft = true)
{
// reset x and y pos before each run
xPos = yPos = 0;
hWndExisting = 0;
string::set_case_sensitive(0);
// find the IDE window
HWND hWndIDE = FindWindow("CPPFRAME", NULL);
// find the MDI client which is the client
// window of the IDE
hWndMDI = FindWindowEx(hWndIDE, NULL, "MDIClient", NULL);
// get a handle to the newly-created editor
hWndNew = FindWindowEx(hWndMDI, NULL, "BCW5Editor", title);
char pszName[MAXFILE];
char pszExt[MAXEXT];
GetNameExt(title,pszName,pszExt);
FileGroup fileGroup = GetFileGroup(pszExt);
if (fileGroup != Other) {
RECT rect;
if(fileGroup == (bSourceInLeft ? Source : Header)) {
GetClientRect(hWndMDI, &rect);
xPos = rect.right - width;
}
strcpy(pszExt,GetCorrespondingExt(fileGroup,pszExt));
char pszNameExt[MAXFILE + MAXEXT + 1];
sprintf(pszNameExt,"%s%s",pszName,pszExt);
EnumChildWindows(hWndMDI, FindExistingWindow, (LPARAM)pszNameExt);
if (hWndExisting) {
POINT point;
GetWindowRect(hWndExisting, &rect);
point.x = rect.left;
point.y = rect.top;
ScreenToClient(hWndMDI, &point);
yPos = point.y;
}
else
EnumChildWindows(hWndMDI, EnumProc, (LPARAM)hWndMDI);
}
else
EnumChildWindows(hWndMDI, EnumProc, (LPARAM)hWndMDI);
if (hWndNew)
SetWindowPos(hWndNew, 0, xPos, yPos, width, height, SWP_NOZORDER);
}
Download MyEdSize.zip
import IDE;
import editor;
declare keyCut = "<Ctrl-h>"; // set a keycut you like
declare kbd = IDE.KeyboardManager.GetKeyboard("Editor");
kbd.Assign(keyCut, "CppH_Tog_Launch();");
print("Show Header assigned to " + keyCut);
CppH_Tog_Launch()
{
// just create an object to do the job
new CppH_Tog_Worker();
}
class CppH_Tog_Worker
{
declare topBuf = editor.TopBuffer;
// validate current buffer
if (!topBuf) {
IDE.StatusBar = "CppH_Tog: Invalid top buffer";
return;
}
// You can customize this mapping to better suit your needs.
// It's simply an array of entries, which are themselves
// an array of 2 elements:
// 1. the source extension (of the currently edited file)
// 2. a list (another array) of corresponding extensions, which
// are checked in order of appearance
//
// Note that I've mapped "cpp" first to "h" and then to "hpp".
// That's because I only use .h headers for .cpp files.
// If you're using .hpp headers they will be opened nicely,
// unless you also have a .h with the same name in the directory
// (for interfacing with C programs).
// In that case, just put "hpp" before "h".
//
declare map = {
{ "cpp", {"h", "hpp"} },
{ "h", {"cpp", "c" } },
{ "c", {"h" } },
{ "hpp", {"cpp" } },
{ "rc", {"rh" } },
{ "rh", {"rc" } }
};
// The next array provides mappings for the directory part
// of the filename.
// It's very useful for toggling between Owl source and
// headers, which are in different paths, e.g.
//
// Owl5
// C:\BC5\SOURCE\OWL\window.cpp
// C:\BC5\INCLUDE\OWL\window.h
//
// OwlNext
// C:\Owl\source\owlcore\window.cpp
// C:\Owl\include\owl\window.h
//
// This array contains string pairs. After scanning the directory
// for an open/existing file, we'll start replacing parts of it
// using the 'dirMap' table. The order of the two strings in each pair
// is not significant, since we'll check for both of them and
// replace whichever we find with the other.
// Each modification will be applied to the original path.
// Note that these 'tokens' are delimited by '\' characters
// to avoid partial replacement of directory names.
//
// The predefined pairs are mainly targeted to:
// 1. searching in the same directory;
// a single NULL causes the path to remain unchanged
// 2. Owl5 files.
// 3. OwlNext files.
// 4. Other cases.
// You can add more pairs, and rearrange their order.
//
declare dirMap = {
NULL,
{"\\include\\", "\\source\\"},
{"\\include\\owl\\", "\\source\\owlcore\\"},
{"\\inc\\", "\\src\\"}
};
// get the parts of the buffer's filename
declare drive = topBuf.Drive;
declare path = topBuf.Directory;
declare fname = topBuf.FileName;
declare ext = topBuf.Extension;
// get a list of mapped extensions
declare mapExt = GetMappedExtensions(ext);
// check for unsupported extensions
if (!mapExt) {
IDE.StatusBar = "CppH_Tog: Unsupported extension (" + ext + ")";
return;
}
//======================================
// STEP 1. Check for an existing buffer
//======================================
declare exBuf = GetExistingBuffer();
if (exBuf) {
HandleExistingBuffer(exBuf);
return; // if the above failed, we shouldn't continue
}
//=========================================
// STEP 2. Check if a matching file exists
//=========================================
// iterate through the mapped extensions to check
// if a matching file exists
declare exFile = GetExistingFile();
if (exFile) {
HandleExistingFile(exFile);
return; // if the above failed, we shouldn't continue
}
//======================================================
// STEP 3. Create a new buffer with the first extension
// in the same directory as a last resort.
//======================================================
// the file doesn't really exist, but we open it anyway
HandleExistingFile(drive + path + fname + "." + mapExt[0]);
// THE END
// ----------------------------------
// MEMBER FUNCTIONS FOLLOW:
// ----------------------------------
// ----------------------------------
// Check whether two strings match, ignoring case.
// ----------------------------------
StrIMatch(s1, s2)
{
s1 = (new String(s1)).Upper().Text;
s2 = (new String(s2)).Upper().Text;
return s1 == s2;
}
// ----------------------------------
// Check whether the specified extension
// exists in the mapping array.
// ----------------------------------
GetMappedExtensions(ext)
{
declare ret = NULL;
declare index; // cannot declare this inside 'iterate's parentheses
iterate (declare entry; map; index)
if (StrIMatch("." + entry[0], ext))
return map[index][1];
// we didn't find it
return NULL;
}
// ----------------------------------
// Return the first existing buffer in the IDE that matches
// the mapped extensions, or NULL if non is found.
// ----------------------------------
GetExistingBuffer()
{
declare sentry = 0;
// apply directory mappings
//
iterate (declare tokPair; dirMap)
{
declare xPath = TransformPath(path, tokPair);
if (xPath == NULL) continue; // in case the path didn't change
// walk the buffer list.
//
// explaining the 'for' loop params:
// init: we start checking the next buffer from the top
// cond: a valid buf and not the top buffer (because buffer list is circular)
// CAUTION: don't use "testBuf && (testBuf != topBuf)", it always evals to FALSE (don't know why...)
// step: the next, non-private buffer
//
for (declare testBuf = topBuf.NextBuffer(false);
(testBuf != NULL) && (testBuf != topBuf);
testBuf = testBuf.NextBuffer(false))
{
// iterate through the mapped extensions to check
// if the buffer matches one of them
iterate (declare testExt; mapExt)
{
if (StrIMatch(drive + xPath + fname + "." + testExt,
testBuf.FullName))
return testBuf;
}
// this sentry will terminate the loop
// in case something goes haywire :)
// (perhaps it's not needed...)
if (++sentry >= 1000) break;
}
}
// we couldn't find a valid buffer
return NULL;
}
// ----------------------------------
// If a matching buffer is found, try to open one of its views
// ----------------------------------
HandleExistingBuffer(exBuf)
{
// does it have any views?
if (exBuf.TopView) {
// (is EditView::Window always non-NULL? docs don't mention returning NULL)
exBuf.TopView.Window.IsHidden = false;
exBuf.TopView.Window.Activate();
}
else {
// there are no views attached;
// create a new window; a default view will be created too
declare newWnd = editor.EditWindowCreate(exBuf);
if (newWnd == NULL) {
IDE.StatusBar = "CppH_Tog: Could create new edit window";
return;
}
}
IDE.StatusBar = "CppH_Tog: OK";
}
// ----------------------------------
// Return the first existing file that matches
// the mapped extensions, or NULL if non is found.
// ----------------------------------
GetExistingFile()
{
// apply directory mappings
//
iterate (declare tokPair; dirMap)
{
declare xPath = TransformPath(path, tokPair);
if (xPath == NULL) continue; // in case the path didn't change
// iterate through the mapped extensions to check
// if the file exists
iterate (declare testExt; mapExt)
{
if (FileExists(drive + xPath + fname + "." + testExt))
return drive + xPath + fname + "." + testExt;
}
}
// we couldn't find an existing file
return NULL;
}
// ----------------------------------
// If a matching file is found, try to create a buffer
// and attach a new view to it.
// (NOTE: Assuming a buffer was not found,
// this function will create a new one)
// ----------------------------------
HandleExistingFile(fname)
{
// create an EditBuffer
declare newBuf = editor.EditBufferCreate(fname);
if (newBuf == NULL) {
IDE.StatusBar = "CppH_Tog: Could create new edit buffer";
return;
}
// create an EditWindow - a default view will be created too
declare newWnd = editor.EditWindowCreate(newBuf);
if (newWnd == NULL) {
IDE.StatusBar = "CppH_Tog: Could create new edit window";
return;
}
IDE.StatusBar = "CppH_Tog: OK";
}
// ----------------------------------
// Accepts a string path and a 'dirMap' entry,
// and returns a modified string path.
// By convention, if 'tokPair' is NULL, 'path' is returned
// (to allow searching in the same directory).
// If no replacement was possible, NULL is returned.
// ----------------------------------
TransformPath(path, pair)
{
if (pair == NULL)
return path;
declare n;
declare sPath = (new String(path )).Upper();
declare sTok1 = (new String(pair[0])).Upper();
declare sTok2 = (new String(pair[1])).Upper();
n = sPath.Index(sTok1.Text);
if (n) return StrReplace(path, --n, sTok1.Length, pair[1]);
n = sPath.Index(sTok2.Text);
if (n) return StrReplace(path, --n, sTok2.Length, pair[0]);
return NULL; // could not replace anything
}
// Replaces 'len' characters of string 'src',
// starting at 'pos', with string 'part'.
//
StrReplace(src, pos, len, part)
{
// note that .SubString(n,0) acts like .SubString(n)
// (i.e. it doesn't return "")
//
declare s = new String(src);
return (pos ? s.SubString(0, pos).Text : "")
+ part + s.SubString(pos + len).Text;
}
};
Download CppH_Tog.zip