View mode: basic / threaded / horizontal-split · Log in · Help
March 04, 2005
Dynamic rectangular arrays
Hello, can someone help me with the following issue regarding dynamic
"rectangular arrays"? Thanks.

-Porting some C code to D.
-The C code allocates, deletes, and resizes a multi-dimensional character array
using malloc/free.
-Don't want to use malloc/free.
-How do I create the array Buffer[][] as dynamic, and set its length?
(ie. Buffer.length = cxBuffer; //obviously won't work)
-If Buffer[][] needs to be deleted and resized, how is this done)? Will
new/delete work, if so how?
-cxBuffer, cyBuffer, and Buffer must be static. They must keep their values when
the function exits.

Kevin M

----------------------------
some_function()
{
int         x, y;
static int  cxBuffer, cyBuffer;

//Initialize cxBuffer and cyBuffer
..

//Create Buffer[][]
static char Buffer[cxBuffer][cyBuffer];

//Initialize Buffer
for (y = 0 ; y < cyBuffer ; y++)
for (x = 0 ; x < cxBuffer ; x++)
Buffer[x][y] = ' ';
}
----------------------------
March 04, 2005
Re: Dynamic rectangular arrays
On Fri, 4 Mar 2005 00:07:51 +0000 (UTC), Kevin M wrote:

> Hello, can someone help me with the following issue regarding dynamic
> "rectangular arrays"? Thanks.
> 
> -Porting some C code to D.
> -The C code allocates, deletes, and resizes a multi-dimensional character array
> using malloc/free.
> -Don't want to use malloc/free.
> -How do I create the array Buffer[][] as dynamic, and set its length?
> (ie. Buffer.length = cxBuffer; //obviously won't work)
> -If Buffer[][] needs to be deleted and resized, how is this done)? Will
> new/delete work, if so how?
> -cxBuffer, cyBuffer, and Buffer must be static. They must keep their values when
> the function exits.
> 
> Kevin M
> 
> ----------------------------
> some_function()
> {
> int         x, y;
> static int  cxBuffer, cyBuffer;
> 
> //Initialize cxBuffer and cyBuffer
> ..
> 
> //Create Buffer[][]
> static char Buffer[cxBuffer][cyBuffer];
> 
> //Initialize Buffer
> for (y = 0 ; y < cyBuffer ; y++)
> for (x = 0 ; x < cxBuffer ; x++)
> Buffer[x][y] = ' ';
> }
> ----------------------------

Here some code that seems to do the job ...
<code>
import std.stdio;
 
void some_function(char pTest)
{
   int         x, y;
   static int  cxBuffer, cyBuffer;
   static char[][] Buffer;

   if (pTest == '\0')
   {
       //Initialize cxBuffer and cyBuffer
       cxBuffer = 40;
       cyBuffer = 23;
       
   
       //Create Buffer[][]
       Buffer.length = cyBuffer;
       foreach( inout char[] B; Buffer)
       {
           B.length = cxBuffer;
           B[0..length] = ' ';
       }
   }
   else
   {
       foreach( inout char[] B; Buffer)
       {
           B[0..length] = pTest;
       }
   }
   
   // Show it's current contents
   foreach(int iLine, char[] Line; Buffer)
   {
       std.stdio.writef("[%2d] '", iLine);
       foreach(char c; Line)
           std.stdio.putchar(c);
       std.stdio.puts("'\n");
   }
}

void main()
{
   char x;
   some_function('\0');
   x = getchar();
   some_function(x);
}
</code>
-- 
Derek Parnell
Melbourne, Australia
http://www.dsource.org/projects/build/
4/03/2005 11:27:10 AM
March 04, 2005
Re: Dynamic rectangular arrays
Here is the actual code, which makes it clearer what I am trying to do with
Buffer[][]. Currently Buffer[200][200] is static, but I want it to be dynamic,
so I can use Buffer[cxBuffer][cyBuffer] instead.

Kevin M

<code>
/*--------------------------------------
TYPER.D -- Typing Program
(c) Charles Petzold, 1998
--------------------------------------*/

// Translated to D Language by Kevin M 3-Mar-2005
//
// ($Revision: 1.7 $)
//
// To compile: dmd typer.d gdi32.lib
//
// Compiler requires win32.def:
//   EXETYPE NT
//   SUBSYSTEM WINDOWS
//
// (user32.lib, winuser.h):
// ------------------------
//   BeginPaint(), CreateCaret(), CreateWindowA()?, DefWindowProcA(),
//   DestroyCaret(), DispatchMessageA(), EndPaint(), GetDC(), GetFocus(),
/
/   GetMessageA(), HideCaret(), InvalidateRect(), LoadCursorA(), LoadIconA(),
//   MessageBoxA(), PostQuitMessage(), RegisterClassA(), ReleaseDC(),
//   SendMessageA(), SetCaretPos(), ShowCaret(), ShowWindow(),
//   TranslateMessage(), UpdateWindow()
//
// (gdi32.lib, wingdi.h):
// ----------------------
//   CreateFontA(), DeleteObject(), GetStockObject(), GetTextMetricsA(),
//   SelectObject(), TextOutA()
//
// (kernel32.lib, winbase.h):
// --------------------------
//   None
//
// (windows.d, windef.h macro):
// ----------------------------
//   HIWORD(), LOWORD()
//

import std.c.windows.windows;
//import std.c.stdlib;          // free(), malloc()

extern (C) void gc_init();
extern (C) void gc_term();
extern (C) void _minit();
extern (C) void _moduleCtor();
extern (C) void _moduleUnitTests();

extern (Windows)
int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
int result;

gc_init();                  // initialize garbage collector
_minit();                   // initialize module constructor table

try
{
_moduleCtor();          // call module constructors
_moduleUnitTests();     // run unit tests (optional)

result = myWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
}

catch (Object o)            // catch any uncaught exceptions
{
MessageBoxA(cast(HWND) null, cast(char *)o.toString(), "Error",
MB_OK | MB_ICONEXCLAMATION);
result = 0;             // failed
}

gc_term();                  // run finalizers; terminate garbage collector
return result;
}

// ************************************************************

//Win32 API header entries missing in C:\dmd\src\phobos\std\c\windows\windows.d
alias char TCHAR;

int max(int a, int b) { return a > b ? a : b; }
int min(int a, int b) { return a < b ? a : b; }

int myWinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR[] szAppName = "Typer" ;
HWND           hwnd ;
MSG            msg ;
WNDCLASS       wndclass ;

wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc   = &WndProc ;
wndclass.cbClsExtra    = 0 ;
wndclass.cbWndExtra    = 0 ;
wndclass.hInstance     = hInstance ;
wndclass.hIcon         = LoadIconA (cast(HINSTANCE) null, IDI_APPLICATION) ;
wndclass.hCursor       = LoadCursorA (cast(HINSTANCE) null, IDC_ARROW) ;
wndclass.hbrBackground = cast(HBRUSH) (GetStockObject (WHITE_BRUSH)) ;
wndclass.lpszMenuName  = cast(LPCSTR) null ;
wndclass.lpszClassName = szAppName ;

if (!RegisterClassA (&wndclass))
{
MessageBoxA (cast(HWND) null, "This program requires Windows NT!",
szAppName, MB_ICONERROR) ;
return 0 ;
}

hwnd = CreateWindowA (szAppName,                  // window class name
"Typing Program",           // window caption
WS_OVERLAPPEDWINDOW,        // window style
CW_USEDEFAULT,              // initial x position
CW_USEDEFAULT,              // initial y position
CW_USEDEFAULT,              // initial x size
CW_USEDEFAULT,              // initial y size
cast(HWND) null,            // parent window handle
cast(HMENU) null,           // window menu handle
hInstance,                  // prog. instance handle
null) ;                     // creation parameters

assert(hwnd);

ShowWindow (hwnd, iCmdShow) ;
UpdateWindow (hwnd) ;

while (GetMessageA (&msg, cast(HWND) null, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessageA (&msg) ;
}
return msg.wParam ;
}

// #define BUFFER(x,y) *(pBuffer + y * cxBuffer + x)

extern (Windows)
int WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static DWORD   dwCharSet = DEFAULT_CHARSET ;
static int     cxChar, cyChar, cxClient, cyClient, cxBuffer, cyBuffer,
xCaret, yCaret ;
//static TCHAR*  pBuffer = null ;
static TCHAR   BUFFER[200][200] ;  // replaces macro BUFFER
HDC            hdc ;
int            x, y, i ;
PAINTSTRUCT    ps ;
TEXTMETRICA    tm ;

switch (message)
{
case WM_INPUTLANGCHANGE:
dwCharSet = wParam ;
// fall through
case WM_CREATE:
hdc = GetDC (hwnd) ;
SelectObject (hdc, CreateFontA (0, 0, 0, 0, 0, 0, 0, 0,
dwCharSet, 0, 0, 0, FIXED_PITCH, cast(LPCSTR) null)) ;

GetTextMetricsA (hdc, &tm) ;
cxChar = tm.tmAveCharWidth ;
cyChar = tm.tmHeight ;

DeleteObject (SelectObject (hdc, GetStockObject (SYSTEM_FONT))) ;
ReleaseDC (hwnd, hdc) ;
// fall through
case WM_SIZE:
// obtain window size in pixels

if (message == WM_SIZE)
{
cxClient = LOWORD (lParam) ;
cyClient = HIWORD (lParam) ;
}
// calculate window size in characters

cxBuffer = max (1, cxClient / cxChar) ;
cyBuffer = max (1, cyClient / cyChar) ;

// allocate memory for buffer and clear it

//if (pBuffer != null)
//     free (pBuffer) ;

//pBuffer = cast(TCHAR*) malloc (cxBuffer * cyBuffer * TCHAR.sizeof) ;

//for (y = 0 ; y < cyBuffer ; y++)
//     for (x = 0 ; x < cxBuffer ; x++)
//          BUFFER[x][y] = ' ' ;

for (y = 0 ; y < 200 ; y++)
for (x = 0 ; x < 200 ; x++)
BUFFER[x][y] = ' ' ;

// set caret to upper left corner

xCaret = 0 ;
yCaret = 0 ;

if (hwnd == GetFocus ())
SetCaretPos (xCaret * cxChar, yCaret * cyChar) ;

InvalidateRect (hwnd, cast(RECT*) null, TRUE) ;
return 0 ;

case WM_SETFOCUS:
// create and show the caret

CreateCaret (hwnd, cast(HBITMAP) null, cxChar, cyChar) ;
SetCaretPos (xCaret * cxChar, yCaret * cyChar) ;
ShowCaret (hwnd) ;
return 0 ;

case WM_KILLFOCUS:
// hide and destroy the caret

HideCaret (hwnd) ;
DestroyCaret () ;
return 0 ;

case WM_KEYDOWN:
switch (wParam)
{
case VK_HOME:
xCaret = 0 ;
break ;

case VK_END:
xCaret = cxBuffer - 1 ;
break ;

case VK_PRIOR:
yCaret = 0 ;
break ;

case VK_NEXT:
yCaret = cyBuffer - 1 ;
break ;

case VK_LEFT:
xCaret = max (xCaret - 1, 0) ;
break ;

case VK_RIGHT:
xCaret = min (xCaret + 1, cxBuffer - 1) ;
break ;

case VK_UP:
yCaret = max (yCaret - 1, 0) ;
break ;

case VK_DOWN:
yCaret = min (yCaret + 1, cyBuffer - 1) ;
break ;

case VK_DELETE:
for (x = xCaret ; x < cxBuffer - 1 ; x++)
BUFFER[x][yCaret] = BUFFER[x + 1][yCaret] ;

BUFFER[cxBuffer - 1][yCaret] = ' ' ;

HideCaret (hwnd) ;
hdc = GetDC (hwnd) ;

SelectObject (hdc, CreateFontA (0, 0, 0, 0, 0, 0, 0, 0,
dwCharSet, 0, 0, 0, FIXED_PITCH, cast(LPCSTR) null)) ;

TextOutA (hdc, xCaret * cxChar, yCaret * cyChar,
& BUFFER[xCaret][yCaret],
cxBuffer - xCaret) ;

DeleteObject (SelectObject (hdc, GetStockObject (SYSTEM_FONT))) ;
ReleaseDC (hwnd, hdc) ;
ShowCaret (hwnd) ;
break ;

default:
break;
}
SetCaretPos (xCaret * cxChar, yCaret * cyChar) ;
return 0 ;

case WM_CHAR:
for (i = 0 ; i < cast(int) LOWORD (lParam) ; i++)
{
switch (wParam)
{
case '\b':                    // backspace
if (xCaret > 0)
{
xCaret-- ;
SendMessageA (hwnd, WM_KEYDOWN, VK_DELETE, 1) ;
}
break ;

case '\t':                    // tab
do
{
SendMessageA (hwnd, WM_CHAR, ' ', 1) ;
}
while (xCaret % 8 != 0) ;
break ;

case '\n':                    // line feed
if (++yCaret == cyBuffer)
yCaret = 0 ;
break ;

case '\r':                    // carriage return
xCaret = 0 ;

if (++yCaret == cyBuffer)
yCaret = 0 ;
break ;

case '\x1B':                  // escape
for (y = 0 ; y < cyBuffer ; y++)
for (x = 0 ; x < cxBuffer ; x++)
BUFFER[x][y] = ' ' ;

xCaret = 0 ;
yCaret = 0 ;

InvalidateRect (hwnd, cast(RECT*) null, FALSE) ;
break ;

default:                      // character codes
BUFFER[xCaret][yCaret] = cast(TCHAR) wParam ;

HideCaret (hwnd) ;
hdc = GetDC (hwnd) ;

SelectObject (hdc, CreateFontA (0, 0, 0, 0, 0, 0, 0, 0,
dwCharSet, 0, 0, 0, FIXED_PITCH, cast(LPCSTR) null)) ;

TextOutA (hdc, xCaret * cxChar, yCaret * cyChar,
& BUFFER[xCaret][yCaret], 1) ;

DeleteObject (
SelectObject (hdc, GetStockObject (SYSTEM_FONT))) ;
ReleaseDC (hwnd, hdc) ;
ShowCaret (hwnd) ;

if (++xCaret == cxBuffer)
{
xCaret = 0 ;

if (++yCaret == cyBuffer)
yCaret = 0 ;
}
break ;
}
}

SetCaretPos (xCaret * cxChar, yCaret * cyChar) ;
return 0 ;

case WM_PAINT:
hdc = BeginPaint (hwnd, &ps) ;

SelectObject (hdc, CreateFontA (0, 0, 0, 0, 0, 0, 0, 0,
dwCharSet, 0, 0, 0, FIXED_PITCH, cast(LPCSTR) null)) ;

for (y = 0 ; y < cyBuffer ; y++)
TextOutA (hdc, 0, y * cyChar, & BUFFER[0][y], cxBuffer) ;

DeleteObject (SelectObject (hdc, GetStockObject (SYSTEM_FONT))) ;
EndPaint (hwnd, &ps) ;
return 0 ;

case WM_DESTROY:
PostQuitMessage (0) ;
return 0 ;

default:
break;
}
return DefWindowProcA (hwnd, message, wParam, lParam) ;
}
</code>

In article <d088sm$2mpk$1@digitaldaemon.com>, Kevin M says...
>
>Hello, can someone help me with the following issue regarding dynamic
>"rectangular arrays"? Thanks.
>
>-Porting some C code to D.
>-The C code allocates, deletes, and resizes a multi-dimensional character array
>using malloc/free.
>-Don't want to use malloc/free.
>-How do I create the array Buffer[][] as dynamic, and set its length?
>(ie. Buffer.length = cxBuffer; //obviously won't work)
>-If Buffer[][] needs to be deleted and resized, how is this done)? Will
>new/delete work, if so how?
>-cxBuffer, cyBuffer, and Buffer must be static. They must keep their values when
>the function exits.
>
>Kevin M
>
>----------------------------
>some_function()
>{
>int         x, y;
>static int  cxBuffer, cyBuffer;
>
>//Initialize cxBuffer and cyBuffer
>..
>
>//Create Buffer[][]
>static char Buffer[cxBuffer][cyBuffer];
>
>//Initialize Buffer
>for (y = 0 ; y < cyBuffer ; y++)
>for (x = 0 ; x < cxBuffer ; x++)
>Buffer[x][y] = ' ';
>}
>----------------------------
>
>
March 04, 2005
Re: Dynamic rectangular arrays - Typer2.d
Attached is the actual code, which makes it clearer what I am trying to do with
Buffer[][]. Currently Buffer[200][200] is static, but I want it to be dynamic,
so I can use Buffer[cxBuffer][cyBuffer] instead.

By the way, how do I keep the Forum from deleting the leading spaces/tabs in
messages? I tried <code> and </code> which didn't work.

Kevin M
March 04, 2005
Re: Dynamic rectangular arrays
On Fri, 4 Mar 2005 01:30:17 +0000 (UTC), Kevin M wrote:

> Here is the actual code, which makes it clearer what I am trying to do with
> Buffer[][]. Currently Buffer[200][200] is static, but I want it to be dynamic,
> so I can use Buffer[cxBuffer][cyBuffer] instead.

I've attached the revised code to make it work.

The main issue is that D and C++ have the order of multi-level indexes
reversed.  Whereas you had basically BUFFER[charindex][lineindex] you will
find that you needed BUFFER[lineindex][charindex]

BTW, I took your code and saved it as 'typer.d', then typed in 'build
typer' and it compiled and linked it first go! This is the first test I've
actually had using my Build utility with a real Windows application so I
was stoked to see it work so easily.

-- 
Derek Parnell
Melbourne, Australia
http://www.dsource.org/projects/build/
4/03/2005 1:06:18 PM
March 04, 2005
Re: Dynamic rectangular arrays - Typer2.d
On Fri, 4 Mar 2005 01:42:48 +0000 (UTC), Kevin M  
<Kevin_member@pathlink.com> wrote:
> Attached is the actual code, which makes it clearer what I am trying to  
> do with
> Buffer[][]. Currently Buffer[200][200] is static, but I want it to be  
> dynamic,
> so I can use Buffer[cxBuffer][cyBuffer] instead.
>
> By the way, how do I keep the Forum from deleting the leading  
> spaces/tabs in
> messages? I tried <code> and </code> which didn't work.

Prefix the line with a character, I know, pain in the a@#$.

For me spaces stay, tabs vanish, at least thats what my posts look like to  
me, who knows what they look like to you.

eg.
    4 spaces
#    4 spaces prefix with #
	1 tab
	 1 tab 1 space

Regan
March 04, 2005
Re: Dynamic rectangular arrays
Here is the actual code again (with indentation), which makes it clearer what I
am trying to do with
Buffer[][]. Currently Buffer[100][200] is static, but I want it to be dynamic,
so I can use Buffer[cyBuffer][cxBuffer] instead.

Kevin M

#/*--------------------------------------
#   TYPER.D -- Typing Program
#              (c) Charles Petzold, 1998
#  --------------------------------------*/
#
#// Translated to D Language by Kevin M 3-Mar-2005
#//
#// ($Revision: 1.8 $)
#//
#// To compile: dmd typer.d gdi32.lib
#//
#// Compiler requires win32.def:
#//   EXETYPE NT
#//   SUBSYSTEM WINDOWS
#//
#// (user32.lib, winuser.h):
#// ------------------------
#//   BeginPaint(), CreateCaret(), CreateWindowA()?, DefWindowProcA(),
#//   DestroyCaret(), DispatchMessageA(), EndPaint(), GetDC(), GetFocus(),
#//   GetMessageA(), HideCaret(), InvalidateRect(), LoadCursorA(), LoadIconA(),
#//   MessageBoxA(), PostQuitMessage(), RegisterClassA(), ReleaseDC(),
#//   SendMessageA(), SetCaretPos(), ShowCaret(), ShowWindow(),
#//   TranslateMessage(), UpdateWindow()
#//
#// (gdi32.lib, wingdi.h):
#// ----------------------
#//   CreateFontA(), DeleteObject(), GetStockObject(), GetTextMetricsA(),
#//   SelectObject(), TextOutA()
#//
#// (kernel32.lib, winbase.h):
#// --------------------------
#//   None
#//
#// (windows.d, windef.h macro):
#// ----------------------------
#//   HIWORD(), LOWORD()
#//
#
#import std.c.windows.windows;
#//import std.c.stdlib;          // free(), malloc()
#
#extern (C) void gc_init();
#extern (C) void gc_term();
#extern (C) void _minit();
#extern (C) void _moduleCtor();
#extern (C) void _moduleUnitTests();
#
#extern (Windows)
#int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
#            LPSTR lpCmdLine, int nCmdShow)
#{
#    int result;
#
#    gc_init();                  // initialize garbage collector
#    _minit();                   // initialize module constructor table
#
#    try
#    {
#        _moduleCtor();          // call module constructors
#        _moduleUnitTests();     // run unit tests (optional)
#
#        result = myWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
#    }
#
#    catch (Object o)            // catch any uncaught exceptions
#    {
#        MessageBoxA(cast(HWND) null, cast(char *)o.toString(), "Error",
#                    MB_OK | MB_ICONEXCLAMATION);
#        result = 0;             // failed
#    }
#
#    gc_term();                  // run finalizers; terminate garbage collector
#    return result;
#}
#
#// ************************************************************
#
#//Win32 API header entries missing in C:\dmd\src\phobos\std\c\windows\windows.d
#alias char TCHAR;
#
#int max(int a, int b) { return a > b ? a : b; }
#int min(int a, int b) { return a < b ? a : b; }
#
#int myWinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
#               PSTR szCmdLine, int iCmdShow)
#{
#     static TCHAR[] szAppName = "Typer" ;
#     HWND           hwnd ;
#     MSG            msg ;
#     WNDCLASS       wndclass ;
#
#     wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
#     wndclass.lpfnWndProc   = &WndProc ;
#     wndclass.cbClsExtra    = 0 ;
#     wndclass.cbWndExtra    = 0 ;
#     wndclass.hInstance     = hInstance ;
#     wndclass.hIcon         = LoadIconA (cast(HINSTANCE) null, IDI_APPLICATION)
;
#     wndclass.hCursor       = LoadCursorA (cast(HINSTANCE) null, IDC_ARROW) ;
#     wndclass.hbrBackground = cast(HBRUSH) (GetStockObject (WHITE_BRUSH)) ;
#     wndclass.lpszMenuName  = cast(LPCSTR) null ;
#     wndclass.lpszClassName = szAppName ;
#
#     if (!RegisterClassA (&wndclass))
#     {
#          MessageBoxA (cast(HWND) null, "This program requires Windows NT!",
#                       szAppName, MB_ICONERROR) ;
#          return 0 ;
#     }
#
#     hwnd = CreateWindowA (szAppName,                  // window class name
#                           "Typing Program",           // window caption
#                           WS_OVERLAPPEDWINDOW,        // window style
#                           CW_USEDEFAULT,              // initial x position
#                           CW_USEDEFAULT,              // initial y position
#                           CW_USEDEFAULT,              // initial x size
#                           CW_USEDEFAULT,              // initial y size
#                           cast(HWND) null,            // parent window handle
#                           cast(HMENU) null,           // window menu handle
#                           hInstance,                  // prog. instance handle
#                           null) ;                     // creation parameters
#
#     assert(hwnd);
#
#     ShowWindow (hwnd, iCmdShow) ;
#     UpdateWindow (hwnd) ;
#
#     while (GetMessageA (&msg, cast(HWND) null, 0, 0))
#     {
#          TranslateMessage (&msg) ;
#          DispatchMessageA (&msg) ;
#     }
#     return msg.wParam ;
#}
#
#// #define BUFFER(x,y) *(pBuffer + y * cxBuffer + x)
#
#extern (Windows)
#int WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
#{
#     static DWORD   dwCharSet = DEFAULT_CHARSET ;
#     static int     cxChar, cyChar, cxClient, cyClient, cxBuffer, cyBuffer,
#                    xCaret, yCaret ;
#   //static TCHAR*  pBuffer = null ;
#     static TCHAR   BUFFER[100][200] ;  // replaces macro BUFFER
#     HDC            hdc ;
#     int            x, y, i ;
#     PAINTSTRUCT    ps ;
#     TEXTMETRICA    tm ;
#
#     switch (message)
#     {
#     case WM_INPUTLANGCHANGE:
#          dwCharSet = wParam ;
#                                        // fall through
#     case WM_CREATE:
#          hdc = GetDC (hwnd) ;
#          SelectObject (hdc, CreateFontA (0, 0, 0, 0, 0, 0, 0, 0,
#                             dwCharSet, 0, 0, 0, FIXED_PITCH, cast(LPCSTR)
null)) ;
#
#          GetTextMetricsA (hdc, &tm) ;
#          cxChar = tm.tmAveCharWidth ;
#          cyChar = tm.tmHeight ;
#
#          DeleteObject (SelectObject (hdc, GetStockObject (SYSTEM_FONT))) ;
#          ReleaseDC (hwnd, hdc) ;
#                                        // fall through
#     case WM_SIZE:
#               // obtain window size in pixels
#
#          if (message == WM_SIZE)
#          {
#               cxClient = LOWORD (lParam) ;
#               cyClient = HIWORD (lParam) ;
#          }
#               // calculate window size in characters
#
#          cxBuffer = max (1, cxClient / cxChar) ;
#          cyBuffer = max (1, cyClient / cyChar) ;
#
#               // allocate memory for buffer and clear it
#
#          //if (pBuffer != null)
#          //     free (pBuffer) ;
#
#          //pBuffer = cast(TCHAR*) malloc (cxBuffer * cyBuffer * TCHAR.sizeof)
;
#
#          //for (y = 0 ; y < cyBuffer ; y++)
#          //     for (x = 0 ; x < cxBuffer ; x++)
#          //          BUFFER[x][y] = ' ' ;
#
#          for (y = 0 ; y < cyBuffer ; y++)
#               for (x = 0 ; x < cxBuffer ; x++)
#                    BUFFER[y][x] = ' ' ;
#
#               // set caret to upper left corner
#
#          xCaret = 0 ;
#          yCaret = 0 ;
#
#          if (hwnd == GetFocus ())
#               SetCaretPos (xCaret * cxChar, yCaret * cyChar) ;
#
#          InvalidateRect (hwnd, cast(RECT*) null, TRUE) ;
#          return 0 ;
#
#     case WM_SETFOCUS:
#               // create and show the caret
#
#          CreateCaret (hwnd, cast(HBITMAP) null, cxChar, cyChar) ;
#          SetCaretPos (xCaret * cxChar, yCaret * cyChar) ;
#          ShowCaret (hwnd) ;
#          return 0 ;
#
#     case WM_KILLFOCUS:
#               // hide and destroy the caret
#
#          HideCaret (hwnd) ;
#          DestroyCaret () ;
#          return 0 ;
#
#     case WM_KEYDOWN:
#          switch (wParam)
#          {
#          case VK_HOME:
#               xCaret = 0 ;
#               break ;
#
#          case VK_END:
#               xCaret = cxBuffer - 1 ;
#               break ;
#
#          case VK_PRIOR:
#               yCaret = 0 ;
#               break ;
#
#          case VK_NEXT:
#               yCaret = cyBuffer - 1 ;
#               break ;
#
#          case VK_LEFT:
#               xCaret = max (xCaret - 1, 0) ;
#               break ;
#
#          case VK_RIGHT:
#               xCaret = min (xCaret + 1, cxBuffer - 1) ;
#               break ;
#
#          case VK_UP:
#               yCaret = max (yCaret - 1, 0) ;
#               break ;
#
#          case VK_DOWN:
#               yCaret = min (yCaret + 1, cyBuffer - 1) ;
#               break ;
#
#          case VK_DELETE:
#               for (x = xCaret ; x < cxBuffer - 1 ; x++)
#                    BUFFER[yCaret][x] = BUFFER[yCaret][x + 1] ;
#
#               BUFFER[yCaret][cxBuffer - 1] = ' ' ;
#
#               HideCaret (hwnd) ;
#               hdc = GetDC (hwnd) ;
#
#               SelectObject (hdc, CreateFontA (0, 0, 0, 0, 0, 0, 0, 0,
#                                  dwCharSet, 0, 0, 0, FIXED_PITCH, cast(LPCSTR)
null)) ;
#
#               TextOutA (hdc, xCaret * cxChar, yCaret * cyChar,
#                         & BUFFER[yCaret][xCaret],
#                         cxBuffer - xCaret) ;
#
#               DeleteObject (SelectObject (hdc, GetStockObject (SYSTEM_FONT)))
;
#               ReleaseDC (hwnd, hdc) ;
#               ShowCaret (hwnd) ;
#               break ;
#
#          default:
#               break;
#          }
#          SetCaretPos (xCaret * cxChar, yCaret * cyChar) ;
#          return 0 ;
#
#     case WM_CHAR:
#          for (i = 0 ; i < cast(int) LOWORD (lParam) ; i++)
#          {
#               switch (wParam)
#               {
#               case '\b':                    // backspace
#                    if (xCaret > 0)
#                    {
#                         xCaret-- ;
#                         SendMessageA (hwnd, WM_KEYDOWN, VK_DELETE, 1) ;
#                    }
#                    break ;
#
#               case '\t':                    // tab
#                    do
#                    {
#                         SendMessageA (hwnd, WM_CHAR, ' ', 1) ;
#                    }
#                    while (xCaret % 8 != 0) ;
#                    break ;
#
#               case '\n':                    // line feed
#                    if (++yCaret == cyBuffer)
#                         yCaret = 0 ;
#                    break ;
#
#               case '\r':                    // carriage return
#                    xCaret = 0 ;
#
#                    if (++yCaret == cyBuffer)
#                         yCaret = 0 ;
#                    break ;
#
#               case '\x1B':                  // escape
#                    for (y = 0 ; y < cyBuffer ; y++)
#                         for (x = 0 ; x < cxBuffer ; x++)
#                              BUFFER[y][x] = ' ' ;
#
#                    xCaret = 0 ;
#                    yCaret = 0 ;
#
#                    InvalidateRect (hwnd, cast(RECT*) null, FALSE) ;
#                    break ;
#
#               default:                      // character codes
#                    BUFFER[yCaret][xCaret] = cast(TCHAR) wParam ;
#
#                    HideCaret (hwnd) ;
#                    hdc = GetDC (hwnd) ;
#
#                    SelectObject (hdc, CreateFontA (0, 0, 0, 0, 0, 0, 0, 0,
#                                       dwCharSet, 0, 0, 0, FIXED_PITCH,
cast(LPCSTR) null)) ;
#
#                    TextOutA (hdc, xCaret * cxChar, yCaret * cyChar,
#                              & BUFFER[yCaret][xCaret], 1) ;
#
#                    DeleteObject (
#                         SelectObject (hdc, GetStockObject (SYSTEM_FONT))) ;
#                    ReleaseDC (hwnd, hdc) ;
#                    ShowCaret (hwnd) ;
#
#                    if (++xCaret == cxBuffer)
#                    {
#                         xCaret = 0 ;
#
#                        if (++yCaret == cyBuffer)
#                              yCaret = 0 ;
#                    }
#                    break ;
#             }
#          }
#
#          SetCaretPos (xCaret * cxChar, yCaret * cyChar) ;
#          return 0 ;
#
#     case WM_PAINT:
#          hdc = BeginPaint (hwnd, &ps) ;
#
#          SelectObject (hdc, CreateFontA (0, 0, 0, 0, 0, 0, 0, 0,
#                             dwCharSet, 0, 0, 0, FIXED_PITCH, cast(LPCSTR)
null)) ;
#
#          for (y = 0 ; y < cyBuffer ; y++)
#               TextOutA (hdc, 0, y * cyChar, & BUFFER[y][0], cxBuffer) ;
#
#          DeleteObject (SelectObject (hdc, GetStockObject (SYSTEM_FONT))) ;
#          EndPaint (hwnd, &ps) ;
#          return 0 ;
#
#     case WM_DESTROY:
#          PostQuitMessage (0) ;
#          return 0 ;
#
#     default:
#          break;
#     }
#     return DefWindowProcA (hwnd, message, wParam, lParam) ;
#}
March 04, 2005
Re: Dynamic rectangular arrays
Derek, thanks for your help. I just tested the code and it works. The Base64
encoding delayed my response.

Kevin M


In article <1t87qzdhec31w$.1q5jqinrfdsuj.dlg@40tude.net>, Derek Parnell says...
>
>----447B463D08905736_message_boundary--
>Content-type: text/plain; charset="us-ascii"
>Content-Transfer-Encoding: 7bit
>
>On Fri, 4 Mar 2005 01:30:17 +0000 (UTC), Kevin M wrote:
>
>> Here is the actual code, which makes it clearer what I am trying to do with
>> Buffer[][]. Currently Buffer[200][200] is static, but I want it to be dynamic,
>> so I can use Buffer[cxBuffer][cyBuffer] instead.
>
>I've attached the revised code to make it work.
>
>The main issue is that D and C++ have the order of multi-level indexes
>reversed.  Whereas you had basically BUFFER[charindex][lineindex] you will
>find that you needed BUFFER[lineindex][charindex]
>
>BTW, I took your code and saved it as 'typer.d', then typed in 'build
>typer' and it compiled and linked it first go! This is the first test I've
>actually had using my Build utility with a real Windows application so I
>was stoked to see it work so easily.
>
>-- 
>Derek Parnell
>Melbourne, Australia
>http://www.dsource.org/projects/build/
>4/03/2005 1:06:18 PM
>----447B463D08905736_message_boundary--
>Content-type: application/octet-string; name=typer.d
>Content-Transfer-Encoding: Base64
>Content-Disposition: attachment; FileName=typer.d
>Content-Description: Attached file: typer.d
>
March 04, 2005
Attachments (was: Dynamic rectangular arrays) - "sort.d" (1/1) uuEncoded 1793 bytes
On Fri, 4 Mar 2005 12:00:43 +0000 (UTC), Kevin M wrote:

> Derek, thanks for your help. I just tested the code and it works. The Base64
> encoding delayed my response.

[snip]

>>----447B463D08905736_message_boundary--
>>Content-type: application/octet-string; name=typer.d
>>Content-Transfer-Encoding: Base64
>>Content-Disposition: attachment; FileName=typer.d
>>Content-Description: Attached file: typer.d
>>

I didn't even realize the 40Tude was set up that way. I've changed it to
UUencode now. It that any better?

-- 
Derek Parnell
Melbourne, Australia
4/03/2005 11:03:46 PM
March 04, 2005
Re: Attachments (was: Dynamic rectangular arrays) -
Derek, I used http://makcoder.sourceforge.net/demo/base64.php to decode the
Base64. I've just installed 40tude, but how do I configure it for this forum?

Kevin

In article <5aqwhkz1z0a5$.h3l070vr6s3i$.dlg@40tude.net>, Derek Parnell says...
>
>On Fri, 4 Mar 2005 12:00:43 +0000 (UTC), Kevin M wrote:
>
>> Derek, thanks for your help. I just tested the code and it works. The Base64
>> encoding delayed my response.
>
>[snip]
>
>>>----447B463D08905736_message_boundary--
>>>Content-type: application/octet-string; name=typer.d
>>>Content-Transfer-Encoding: Base64
>>>Content-Disposition: attachment; FileName=typer.d
>>>Content-Description: Attached file: typer.d
>>>
>
>I didn't even realize the 40Tude was set up that way. I've changed it to
>UUencode now. It that any better?
>
>-- 
>Derek Parnell
>Melbourne, Australia
>4/03/2005 11:03:46 PM
>begin 644 sort.d
>M+R\@<V]R="YD#0HO+R!"87-E9"!O;B!T:&4@175P:&]R:6$@,BXU('-O<G0N
>M92!B>2!2;V)E<G0@0W)A:6<N#0IM;V1U;&4@<V]R=#L-"@T*=&5M<&QA=&4@
>M5%-H96QL4V]R="A4*0T*>PT*=F]I9"!S;W)T*%1;72!X+"!I;G0@9G5N8W1I
>M;VXH5"!A+"!4(&(I(&8];G5L;"D-"GL-"B\O("`M+2!3;W)T(&%N(&%R<F%Y
>M(&EN=&\@87-C96YD:6YG(&]R9&5R#0H-"B`@("!I;G0@9V%P+"!J+"!F:7)S
>M="P@;&%S=#L-"B`@("!B;V]L(&-M<#L-"B`@("!4('1E;7!I+"!T96UP:CL-
>M"@T*("`@(&QA<W0@/2!X+FQE;F=T:#L-"B`@("!G87`@/2`H;&%S="`O(#$P
>M*2LQ.PT*("`@('=H:6QE("AT<G5E*0T*("`@('L-"B`@("!F:7)S="`](&=A
>M<"`K(#$[#0H@("`@9F]R("AI;G0@:2`](&9I<G-T.R!I(#P](&QA<W0[(&DK
>M*RD-"B`@("![#0H@("`@("`@('1E;7!I(#T@>%MI+3%=.PT*("`@("`@("!J
>M(#T@:2`M(&=A<#L-"B`@("`@("`@=VAI;&4@*'1R=64I#0H@("`@("`@('L-
>M"B`@("`@("`@=&5M<&H@/2!X6VHM,5T[#0H@("`@("`@(&EF("AF(&ES(&YU
>M;&PI#0H@("`@("`@("`@("!C;7`@/2`H=&5M<&D@/CT@=&5M<&HI.PT*("`@
>M("`@("!E;'-E#0H@("`@("`@("`@("!C;7`@/2`H9BAT96UP:2P@=&5M<&HI
>M(#X](#`I.PT*("`@("`@("`@("`@#0H@("`@("`@(&EF("AC;7`I('L-"B`@
>M("`@("`@("`@(&H@*ST@9V%P.PT*("`@("`@("`@("`@8G)E86L[#0H@("`@
>M("`@('T-"B`@("`@("`@#0H@("`@("`@('A;:BMG87`M,5T@/2!T96UP:CL-
>M"B`@("`@("`@:68@*&H@/#T@9V%P*0T*("`@("`@("`@("`@8G)E86L[#0H-
>M"B`@("`@("`@:B`M/2!G87`[#0H@("`@("`@('T-"B`@("`@("`@#0H@("`@
>M("`@('A;:BTQ72`]('1E;7!I.PT*("`@('T-"B`@("!I9B`H9V%P(#T](#$I
>M#0H@("`@("`@(')E='5R;B`[#0H-"B`@("!G87`@/2!C87-T*&EN="DH9V%P
>M("\@,RXU*2`K(#$[#0H-"B`@("!]#0I]#0I]#0H-"B!A;&EA<R!44VAE;&Q3
>M;W)T(2AI;G0I+G-O<G0@<V]R=#L-"B!A;&EA<R!44VAE;&Q3;W)T(2AC:&%R
>M6UTI+G-O<G0@<V]R=#L-"B`-"G!R:79A=&4@:6UP;W)T('-T9"YS=&1I;SL-
>M"@T*<')I=F%T92!I;G0@;7EC;VUP*"!C:&%R6UT@82P@8VAA<EM=(&(I#0I[
>M#0H@("!I9B`H82YL96YG=&@@/B!B+FQE;F=T:"D@#0H@("`@<F5T=7)N(#$[
>M#0H@("!I9B`H82YL96YG=&@@/"!B+FQE;F=T:"D@#0H@("`@<F5T=7)N("TQ
>M.PT*("`@:68@*&$@/B!B*2`-"B`@("!R971U<FX@,3L-"B`@(&EF("AA(#P@
>M8BD@#0H@("`@<F5T=7)N("TQ.PT*("`@<F5T=7)N(#`[#0I]#0IU;FET=&5S
>M='L@#0H@("`@=W)I=&5F;&XH(G-O<G0N9"!5;FET(%1E<W1I;F<B*3L-"B`@
>M("!C:&%R6UU;72!!.PT*("`@($$@?CT@(F]N92([#0H@("`@02!^/2`B='=O
>M(CL-"B`@("!!('X](")T:')E92([#0H@("`@02!^/2`B9F]U<B([#0H@("`@
>M02!^/2`B9FEV92([#0H@("`@02!^/2`B<VEX(CL-"B`@("!!('X](")S979E
>M;B([#0H@("`@02!^/2`B96EG:'0B.PT*("`@($$@?CT@(FYI;F4B.PT*("`@
>M($$@?CT@(G1E;B([#0H@("`@#0H@("`@=W)I=&5F;&XH(E1E<W0@=VET:"!C
>M=7-T;VUI>F5D(&-O;7!A<FES:6]N(')O=71I;F4N(BD[#0H@("`@<V]R="A!
>M+"`F;7EC;VUP*3L-"B`@("!F;W)E86-H*&-H87);72!X.R!!*0T*("`@("`@
>M('=R:71E9FQN*'@I.PT*("`@(`T*("`@('=R:71E9FQN*")497-T('=I=&@@
>M;F]R;6%L(&-O;7!A<F5S+B(I.PT*("`@('-O<G0H02D[#0H@("`@9F]R96%C
>F:"AC:&%R6UT@>#L@02D-"B`@("`@("!W<FET969L;BAX*3L-"GT`
>`
>end
>
« First   ‹ Prev
1 2
Top | Discussion index | About this forum | D home