www.digitalmars.com         C & C++   DMDScript  

c++.announce - DM C/C++ 8.35 release

reply "Walter" <walter digitalmars.com> writes:
An accummulation of a lot of minor fixes. Now has STLSoft 1.6.5.

http://www.digitalmars.com/compiler.htm
Aug 23 2003
next sibling parent reply "Matthew Wilson" <matthew stlsoft.org> writes:
Excuse please, as may have jettisoned an important part of the brain as a
result of all that late night testing of 8.35b, but ...

   Where do I get the latest DMC++ MFC?

"Walter" <walter digitalmars.com> wrote in message
news:bi8tir$loe$1 digitaldaemon.com...
 An accummulation of a lot of minor fixes. Now has STLSoft 1.6.5.

 http://www.digitalmars.com/compiler.htm

Aug 23 2003
parent reply "Walter" <walter digitalmars.com> writes:
It comes on the CD. If you have an older CD, and install the CD updates in
order, you should wind up with the latest.

    Where do I get the latest DMC++ MFC?

Aug 23 2003
parent "Greg Peet" <admin gregpeet.com> writes:
I think he means where's the upgrade for the CD:
http://www.digitalmars.com/download/freecompiler.html
The upgrade for CD owners is at the bottom.

"Walter" <walter digitalmars.com> wrote in message
news:bi9cma$1aen$1 digitaldaemon.com...
| It comes on the CD. If you have an older CD, and install the CD updates in
| order, you should wind up with the latest.
|
| >    Where do I get the latest DMC++ MFC?
|
|
Aug 25 2003
prev sibling next sibling parent reply "Greg Peet" <admin gregpeet.com> writes:
Hi Walter,
    You mention rebuilding STLport though I get a clean return on smake -f
dm.mak (meaning there is nothing to be built).
Where there any changes made to STLport since 8.34? Or am I a fool and need
to remove all the lib's and dll's and just rebuild? =)

Thanks

"Walter" <walter digitalmars.com> wrote in message
news:bi8tir$loe$1 digitaldaemon.com...
| An accummulation of a lot of minor fixes. Now has STLSoft 1.6.5.
|
| http://www.digitalmars.com/compiler.htm
|
|
|
Aug 25 2003
parent reply "Walter" <walter digitalmars.com> writes:
     You mention rebuilding STLport though I get a clean return on smake -f
 dm.mak (meaning there is nothing to be built).
 Where there any changes made to STLport since 8.34? Or am I a fool and

 to remove all the lib's and dll's and just rebuild? =)

No source changes made. I rebuilt it just to ensure that 8.35 could <g>.
Aug 25 2003
parent reply Cesar Rabak <csrabak uol.com.br> writes:
Walter escreveu:
 You mention rebuilding STLport though I get a clean return on smake
 -f dm.mak (meaning there is nothing to be built). Where there any
 changes made to STLport since 8.34? Or am I a fool and

need
 to remove all the lib's and dll's and just rebuild? =)

No source changes made. I rebuilt it just to ensure that 8.35 could <g>.

hello.cpp STLPort example I get an error I did not used to get: C:\DM\stlport>sc hello -I\dm\stlport\stlport link hello,,,user32+kernel32/noi; OPTLINK (R) for Win32 Release 7.50B1 Copyright (C) Digital Mars 1989 - 2001 All Rights Reserved C:\DM\BIN\..\lib\SNN.lib(except) Offset 06F3FH Record Type 00C3 Error 1: Previous Definition Different : ??1exception std UAE XZ (syscall std: :exception::~exception(void )) C:\DM\BIN\..\lib\SNN.lib(except) Offset 0703AH Record Type 00C3 Error 1: Previous Definition Different : ?what exception std UBEPBDXZ (char co nst *syscall std::exception::what(void )const ) C:\DM\BIN\..\lib\SNN.lib(except) Offset 07131H Record Type 00C3 Error 1: Previous Definition Different : ??1bad_exception std UAE XZ (syscall std::bad_exception::~bad_exception(void )) C:\DM\BIN\..\lib\SNN.lib(except) Offset 071EFH Record Type 00C3 Error 1: Previous Definition Different : ?what bad_exception std UBEPBDXZ (cha r const *syscall std::bad_exception::what(void )const ) --- errorlevel 4 Perhaps I have to recompile some library? -- Cesar Rabak GNU/Linux User 52247. Get counted: http://counter.li.org/
Aug 25 2003
next sibling parent reply "Walter" <walter digitalmars.com> writes:
Email me the source to your hello.cpp.

"Cesar Rabak" <csrabak uol.com.br> wrote in message
news:3F4A468A.2080303 uol.com.br...
 Walter escreveu:
  >> You mention rebuilding STLport though I get a clean return on smake
  >> -f dm.mak (meaning there is nothing to be built). Where there any
  >> changes made to STLport since 8.34? Or am I a fool and
  >
  > need
  >
  >> to remove all the lib's and dll's and just rebuild? =)
  >
  >
  > No source changes made. I rebuilt it just to ensure that 8.35 could
  > <g>.
  >
 Interestingly, after I applied the CD upgrade, when I try to compile the
 hello.cpp STLPort example I get an error I did not used to get:

 C:\DM\stlport>sc hello -I\dm\stlport\stlport
 link hello,,,user32+kernel32/noi;
 OPTLINK (R) for Win32  Release 7.50B1
 Copyright (C) Digital Mars 1989 - 2001  All Rights Reserved

 C:\DM\BIN\..\lib\SNN.lib(except)  Offset 06F3FH Record Type 00C3
   Error 1: Previous Definition Different : ??1exception std  UAE XZ
 (syscall std:
 :exception::~exception(void ))
 C:\DM\BIN\..\lib\SNN.lib(except)  Offset 0703AH Record Type 00C3
   Error 1: Previous Definition Different : ?what exception std  UBEPBDXZ
 (char co
 nst *syscall std::exception::what(void )const )
 C:\DM\BIN\..\lib\SNN.lib(except)  Offset 07131H Record Type 00C3
   Error 1: Previous Definition Different : ??1bad_exception std  UAE XZ
 (syscall
 std::bad_exception::~bad_exception(void ))
 C:\DM\BIN\..\lib\SNN.lib(except)  Offset 071EFH Record Type 00C3
   Error 1: Previous Definition Different :
 ?what bad_exception std  UBEPBDXZ (cha
 r const *syscall std::bad_exception::what(void )const )

 --- errorlevel 4

 Perhaps I have to recompile some library?

 --
 Cesar Rabak
 GNU/Linux User 52247.
 Get counted: http://counter.li.org/

Aug 25 2003
parent reply Cesar Rabak <csrabak uol.com.br> writes:
Walter escreveu:
 Email me the source to your hello.cpp.
 

Is this file which comes w/STLPort: <quote> #include <iostream> int main() { std::cout << "Hello world\n"; } </quote>
 "Cesar Rabak" <csrabak uol.com.br> wrote in message
 news:3F4A468A.2080303 uol.com.br...
 
Walter escreveu:
 You mention rebuilding STLport though I get a clean return on smake
 -f dm.mak (meaning there is nothing to be built). Where there any
 changes made to STLport since 8.34? Or am I a fool and

need
 to remove all the lib's and dll's and just rebuild? =)

No source changes made. I rebuilt it just to ensure that 8.35 could <g>.

hello.cpp STLPort example I get an error I did not used to get: C:\DM\stlport>sc hello -I\dm\stlport\stlport link hello,,,user32+kernel32/noi; OPTLINK (R) for Win32 Release 7.50B1 Copyright (C) Digital Mars 1989 - 2001 All Rights Reserved C:\DM\BIN\..\lib\SNN.lib(except) Offset 06F3FH Record Type 00C3 Error 1: Previous Definition Different : ??1exception std UAE XZ (syscall std: :exception::~exception(void )) C:\DM\BIN\..\lib\SNN.lib(except) Offset 0703AH Record Type 00C3 Error 1: Previous Definition Different : ?what exception std UBEPBDXZ (char co nst *syscall std::exception::what(void )const ) C:\DM\BIN\..\lib\SNN.lib(except) Offset 07131H Record Type 00C3 Error 1: Previous Definition Different : ??1bad_exception std UAE XZ (syscall std::bad_exception::~bad_exception(void )) C:\DM\BIN\..\lib\SNN.lib(except) Offset 071EFH Record Type 00C3 Error 1: Previous Definition Different : ?what bad_exception std UBEPBDXZ (cha r const *syscall std::bad_exception::what(void )const ) --- errorlevel 4 Perhaps I have to recompile some library? -- Cesar Rabak GNU/Linux User 52247. Get counted: http://counter.li.org/


-- Cesar Rabak GNU/Linux User 52247. Get counted: http://counter.li.org/
Aug 25 2003
parent reply "Walter" <walter digitalmars.com> writes:
Just tried it, it works. Sigh. Try rebuilding the stlport libs.

"Cesar Rabak" <csrabak uol.com.br> wrote in message
news:3F4AA777.9020601 uol.com.br...
 Walter escreveu:
 Email me the source to your hello.cpp.

Is this file which comes w/STLPort: <quote> #include <iostream> int main() { std::cout << "Hello world\n"; } </quote>
 "Cesar Rabak" <csrabak uol.com.br> wrote in message
 news:3F4A468A.2080303 uol.com.br...

Walter escreveu:
 You mention rebuilding STLport though I get a clean return on smake
 -f dm.mak (meaning there is nothing to be built). Where there any
 changes made to STLport since 8.34? Or am I a fool and

need
 to remove all the lib's and dll's and just rebuild? =)

No source changes made. I rebuilt it just to ensure that 8.35 could <g>.

hello.cpp STLPort example I get an error I did not used to get: C:\DM\stlport>sc hello -I\dm\stlport\stlport link hello,,,user32+kernel32/noi; OPTLINK (R) for Win32 Release 7.50B1 Copyright (C) Digital Mars 1989 - 2001 All Rights Reserved C:\DM\BIN\..\lib\SNN.lib(except) Offset 06F3FH Record Type 00C3 Error 1: Previous Definition Different : ??1exception std UAE XZ (syscall std: :exception::~exception(void )) C:\DM\BIN\..\lib\SNN.lib(except) Offset 0703AH Record Type 00C3 Error 1: Previous Definition Different : ?what exception std UBEPBDXZ (char co nst *syscall std::exception::what(void )const ) C:\DM\BIN\..\lib\SNN.lib(except) Offset 07131H Record Type 00C3 Error 1: Previous Definition Different : ??1bad_exception std UAE XZ (syscall std::bad_exception::~bad_exception(void )) C:\DM\BIN\..\lib\SNN.lib(except) Offset 071EFH Record Type 00C3 Error 1: Previous Definition Different : ?what bad_exception std UBEPBDXZ (cha r const *syscall std::bad_exception::what(void )const ) --- errorlevel 4 Perhaps I have to recompile some library? -- Cesar Rabak GNU/Linux User 52247. Get counted: http://counter.li.org/


-- Cesar Rabak GNU/Linux User 52247. Get counted: http://counter.li.org/

Aug 25 2003
parent Cesar Rabak <csrabak uol.com.br> writes:
Walter escreveu:
 Just tried it, it works. Sigh. Try rebuilding the stlport libs.
 

Thanks, Walter and Greg.
 "Cesar Rabak" <csrabak uol.com.br> wrote in message
 news:3F4AA777.9020601 uol.com.br...
 
Walter escreveu:

Email me the source to your hello.cpp.

Is this file which comes w/STLPort: <quote> #include <iostream> int main() { std::cout << "Hello world\n"; } </quote>


-- Cesar Rabak GNU/Linux User 52247. Get counted: http://counter.li.org/
Aug 26 2003
prev sibling parent reply "Greg Peet" <admin gregpeet.com> writes:
Did you upgrade from 8.34 to 8.35 or from an earlier, previous one to 8.35?

"Cesar Rabak" <csrabak uol.com.br> wrote in message
news:3F4A468A.2080303 uol.com.br...
| Walter escreveu:
|  >> You mention rebuilding STLport though I get a clean return on smake
|  >> -f dm.mak (meaning there is nothing to be built). Where there any
|  >> changes made to STLport since 8.34? Or am I a fool and
|  >
|  > need
|  >
|  >> to remove all the lib's and dll's and just rebuild? =)
|  >
|  >
|  > No source changes made. I rebuilt it just to ensure that 8.35 could
|  > <g>.
|  >
| Interestingly, after I applied the CD upgrade, when I try to compile the
| hello.cpp STLPort example I get an error I did not used to get:
|
| C:\DM\stlport>sc hello -I\dm\stlport\stlport
| link hello,,,user32+kernel32/noi;
| OPTLINK (R) for Win32  Release 7.50B1
| Copyright (C) Digital Mars 1989 - 2001  All Rights Reserved
|
| C:\DM\BIN\..\lib\SNN.lib(except)  Offset 06F3FH Record Type 00C3
|   Error 1: Previous Definition Different : ??1exception std  UAE XZ
| (syscall std:
| :exception::~exception(void ))
| C:\DM\BIN\..\lib\SNN.lib(except)  Offset 0703AH Record Type 00C3
|   Error 1: Previous Definition Different : ?what exception std  UBEPBDXZ
| (char co
| nst *syscall std::exception::what(void )const )
| C:\DM\BIN\..\lib\SNN.lib(except)  Offset 07131H Record Type 00C3
|   Error 1: Previous Definition Different : ??1bad_exception std  UAE XZ
| (syscall
| std::bad_exception::~bad_exception(void ))
| C:\DM\BIN\..\lib\SNN.lib(except)  Offset 071EFH Record Type 00C3
|   Error 1: Previous Definition Different :
| ?what bad_exception std  UBEPBDXZ (cha
| r const *syscall std::bad_exception::what(void )const )
|
| --- errorlevel 4
|
| Perhaps I have to recompile some library?
|
| -- 
| Cesar Rabak
| GNU/Linux User 52247.
| Get counted: http://counter.li.org/
|
Aug 25 2003
parent reply Cesar Rabak <csrabak uol.com.br> writes:
Greg Peet escreveu:
 Did you upgrade from 8.34 to 8.35 or from an earlier, previous one to 8.35?

I upgraded from 8.34. I've keeping my installation uptodate since ver 8.26.
 
 "Cesar Rabak" <csrabak uol.com.br> wrote in message
 news:3F4A468A.2080303 uol.com.br...
 | Walter escreveu:
 |  >> You mention rebuilding STLport though I get a clean return on smake
 |  >> -f dm.mak (meaning there is nothing to be built). Where there any
 |  >> changes made to STLport since 8.34? Or am I a fool and
 |  >
 |  > need
 |  >
 |  >> to remove all the lib's and dll's and just rebuild? =)
 |  >
 |  >
 |  > No source changes made. I rebuilt it just to ensure that 8.35 could
 |  > <g>.
 |  >
 | Interestingly, after I applied the CD upgrade, when I try to compile the
 | hello.cpp STLPort example I get an error I did not used to get:
 |
 | C:\DM\stlport>sc hello -I\dm\stlport\stlport
 | link hello,,,user32+kernel32/noi;
 | OPTLINK (R) for Win32  Release 7.50B1
 | Copyright (C) Digital Mars 1989 - 2001  All Rights Reserved
 |
 | C:\DM\BIN\..\lib\SNN.lib(except)  Offset 06F3FH Record Type 00C3
 |   Error 1: Previous Definition Different : ??1exception std  UAE XZ
 | (syscall std:
 | :exception::~exception(void ))
 | C:\DM\BIN\..\lib\SNN.lib(except)  Offset 0703AH Record Type 00C3
 |   Error 1: Previous Definition Different : ?what exception std  UBEPBDXZ
 | (char co
 | nst *syscall std::exception::what(void )const )
 | C:\DM\BIN\..\lib\SNN.lib(except)  Offset 07131H Record Type 00C3
 |   Error 1: Previous Definition Different : ??1bad_exception std  UAE XZ
 | (syscall
 | std::bad_exception::~bad_exception(void ))
 | C:\DM\BIN\..\lib\SNN.lib(except)  Offset 071EFH Record Type 00C3
 |   Error 1: Previous Definition Different :
 | ?what bad_exception std  UBEPBDXZ (cha
 | r const *syscall std::bad_exception::what(void )const )
 |
 | --- errorlevel 4
 |
 | Perhaps I have to recompile some library?
 |
 | -- 
 | Cesar Rabak
 | GNU/Linux User 52247.
 | Get counted: http://counter.li.org/
 |
 
 

-- Cesar Rabak GNU/Linux User 52247. Get counted: http://counter.li.org/
Aug 25 2003
parent reply "Greg Peet" <admin gregpeet.com> writes:
"Cesar Rabak" <csrabak uol.com.br> wrote in message
news:3F4AAF18.3060501 uol.com.br...
| I upgraded from 8.34. I've keeping my installation uptodate since ver
8.26.

That is very weird then. It happened to me once. The only sure way to get
STLport working again would be to remove all of the libs/dlls and rebuild.
For example (in console) [assuming your Digital Mars installation is c:\dm]:

    del c:\dm\stlport\lib\stlp45*.lib
    del c:\dm\lib\stlp45*.lib

    del c:\dm\stlport\lib\stlp45*.dll
    del c:\dm\bin\stlp45*.dll

and then:

    cd c:\dm\stlport\stlport
    smake -f dm.mak

and finally:

    xcopy c:\dm\stlport\lib\*.lib c:\dm\lib
    xcopy c:\dm\stlport\lib\*.dll c:\dm\bin
Aug 25 2003
parent Cesar Rabak <csrabak uol.com.br> writes:
As it seems to be customary to top post in this NG, please see below!

Greg Peet escreveu:
 "Cesar Rabak" <csrabak uol.com.br> wrote in message
 news:3F4AAF18.3060501 uol.com.br... | I upgraded from 8.34. I've
 keeping my installation uptodate since ver 8.26.

 That is very weird then. It happened to me once. The only sure way to
 get STLport working again would be to remove all of the libs/dlls and
 rebuild.

Just did it and came back to full steam!
 For example (in console) [assuming your Digital Mars installation is
 c:\dm]:

 del c:\dm\stlport\lib\stlp45*.lib del c:\dm\lib\stlp45*.lib

 del c:\dm\stlport\lib\stlp45*.dll del c:\dm\bin\stlp45*.dll

Since this NG becomes reference, I want to point from your instructions, that:
 and then:

 cd c:\dm\stlport\stlport smake -f dm.mak

cd c:\dm\stlport\src smake -f dm.mak
 and finally:

 xcopy c:\dm\stlport\lib\*.lib c:\dm\lib xcopy c:\dm\stlport\lib\*.dll
 c:\dm\bin

'install' target in the makefile? Better if it moved instead of copying because the libraries created take about 50 Mbytes! By the same token couldn't we have a 'clean' target as well? About other 100 Meg! Thanks, -- Cesar Rabak GNU/Linux User 52247. Get counted: http://counter.li.org/
Aug 30 2003
prev sibling next sibling parent reply chris elliott <biol75 york.ac.uk> writes:
this release still has a bug compiling current wxWindows source (it was 
ok in 8.34)

dmc -c -cpp -Ae -Ar -mn -D_WINDOWS -6 -a8 -Nc -c -H -HD..\..\d_mars -HO- 
-DWXMSW
  -D__WIN32__ -D__WIN95__ -D__WXDEBUG__  -I..\..\include -I..\..\lib\_sc 
-I..\..\
contrib\include 
-I..\../src/regex;..\../src/png;..\../src/jpeg;..\../src/zlib;..
\../src/tiff  ..\..\src\generic\gridsel.cpp -o..\..\src\generic\gridsel.obj
Internal error: type 355
--- errorlevel 1


D:\wx\wxWindows\src\msw>scppn
Digital Mars C/C++ Compiler Version 8.35.10n
Copyright (C) Digital Mars 2000-2003.  All Rights Reserved.
Written by Walter Bright
www.digitalmars.com

chris

Walter wrote:
 An accummulation of a lot of minor fixes. Now has STLSoft 1.6.5.
 
 http://www.digitalmars.com/compiler.htm
 
 
 

Aug 25 2003
parent reply Arjan Knepper <arjan ask.me> writes:
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit

Walter,

Any suggestions how to isolate such errors?

I have isolated two identical blocks of code in two separated member 
functions causing this error, but tearing it apart into a new file, 
makes the error disappear.

The strange thing is when I comment the first code block out the error 
355 still occurs in the second code block, but changing the first code 
block a little makes also the error disappear for the _unmodified_ 
second block of code.

attached the file.

p.s. This file could also be used as work around for DMC 8.35 and 
wxWindows-2.4.1 and the current cvs.


Arjan

chris elliott wrote:

 this release still has a bug compiling current wxWindows source (it was 
 ok in 8.34)
 
 dmc -c -cpp -Ae -Ar -mn -D_WINDOWS -6 -a8 -Nc -c -H -HD..\..\d_mars -HO- 
 -DWXMSW
  -D__WIN32__ -D__WIN95__ -D__WXDEBUG__  -I..\..\include -I..\..\lib\_sc 
 -I..\..\
 contrib\include 
 -I..\../src/regex;..\../src/png;..\../src/jpeg;..\../src/zlib;..
 \../src/tiff  ..\..\src\generic\gridsel.cpp -o..\..\src\generic\gridsel.obj
 Internal error: type 355
 --- errorlevel 1
 
 
 D:\wx\wxWindows\src\msw>scppn
 Digital Mars C/C++ Compiler Version 8.35.10n
 Copyright (C) Digital Mars 2000-2003.  All Rights Reserved.
 Written by Walter Bright
 www.digitalmars.com
 
 chris
 
 Walter wrote:
 
 An accummulation of a lot of minor fixes. Now has STLSoft 1.6.5.

 http://www.digitalmars.com/compiler.htm


Aug 25 2003
next sibling parent "Walter" <walter digitalmars.com> writes:
The only way is to keep deleting code until it disappears. About 99% of such
problems can be isolated down to 20 or less lines of code.

"Arjan Knepper" <arjan ask.me> wrote in message
news:bie115$28vl$1 digitaldaemon.com...
 Walter,

 Any suggestions how to isolate such errors?

 I have isolated two identical blocks of code in two separated member
 functions causing this error, but tearing it apart into a new file,
 makes the error disappear.

 The strange thing is when I comment the first code block out the error
 355 still occurs in the second code block, but changing the first code
 block a little makes also the error disappear for the _unmodified_
 second block of code.

 attached the file.

 p.s. This file could also be used as work around for DMC 8.35 and
 wxWindows-2.4.1 and the current cvs.


 Arjan

 chris elliott wrote:

 this release still has a bug compiling current wxWindows source (it was
 ok in 8.34)

 dmc -c -cpp -Ae -Ar -mn -D_WINDOWS -6 -a8 -Nc -c -H -HD..\..\d_mars -HO-
 -DWXMSW
  -D__WIN32__ -D__WIN95__ -D__WXDEBUG__  -I..\..\include -I..\..\lib\_sc
 -I..\..\
 contrib\include
 -I..\../src/regex;..\../src/png;..\../src/jpeg;..\../src/zlib;..
 \../src/tiff


 Internal error: type 355
 --- errorlevel 1


 D:\wx\wxWindows\src\msw>scppn
 Digital Mars C/C++ Compiler Version 8.35.10n
 Copyright (C) Digital Mars 2000-2003.  All Rights Reserved.
 Written by Walter Bright
 www.digitalmars.com

 chris

 Walter wrote:

 An accummulation of a lot of minor fixes. Now has STLSoft 1.6.5.

 http://www.digitalmars.com/compiler.htm



---------------------------------------------------------------------------- ----

 // Name:        generic/gridsel.cpp
 // Purpose:     wxGridSelection
 // Author:      Stefan Neis
 // Modified by:
 // Created:     20/02/1999
 // RCS-ID:      $Id: gridsel.cpp,v 1.1.1.1 2003/08/14 11:51:46 arjan Exp $
 // Copyright:   (c) Stefan Neis (Stefan.Neis t-online.de)
 // Licence:     wxWindows licence

/
 //

 // declarations
 //


---
 // headers

---
 #ifdef __GNUG__
     #pragma implementation "gridsel.h"
 #endif

 // For compilers that support precompilation, includes "wx/wx.h".
 #include "wx/wxprec.h"

 #include "wx/defs.h"

 #ifdef __BORLANDC__
     #pragma hdrstop
 #endif

 #if defined(wxUSE_NEW_GRID) && (wxUSE_NEW_GRID)

 #include "wx/generic/gridsel.h"

 // Some explanation for the members of the class:
 // m_cellSelection stores individual selected cells
 //   -- this is only used if m_selectionMode == wxGridSelectCells
 // m_blockSelectionTopLeft and m_blockSelectionBottomRight
 //   store the upper left and lower right corner of selected Blocks
 // m_rowSelection and m_colSelection store individual selected
 //   rows and columns; maybe those are superfluous and should be
 //   treated as blocks?

 wxGridSelection::wxGridSelection( wxGrid * grid,
                                   wxGrid::wxGridSelectionModes sel )
 {
     m_grid = grid;
     m_selectionMode = sel;
 }

 bool wxGridSelection::IsSelection()
 {
   return ( m_cellSelection.GetCount() ||

            m_rowSelection.GetCount() || m_colSelection.GetCount() );
 }

 bool wxGridSelection::IsInSelection ( int row, int col )
 {
     size_t count;

     // First check whether the given cell is individually selected
     // (if m_selectionMode is wxGridSelectCells).
     if ( m_selectionMode == wxGrid::wxGridSelectCells )
     {
         count = m_cellSelection.GetCount();
         for ( size_t n = 0; n < count; n++ )
         {
             wxGridCellCoords& coords = m_cellSelection[n];
             if ( row == coords.GetRow() && col == coords.GetCol() )
                 return TRUE;
         }
     }

     // Now check whether the given cell is
     // contained in one of the selected blocks.
     count = m_blockSelectionTopLeft.GetCount();
     for ( size_t n = 0; n < count; n++ )
     {
         wxGridCellCoords& coords1 = m_blockSelectionTopLeft[n];
         wxGridCellCoords& coords2 = m_blockSelectionBottomRight[n];
         if ( BlockContainsCell(coords1.GetRow(), coords1.GetCol(),
                                coords2.GetRow(), coords2.GetCol(),
                                row, col ) )
             return TRUE;
     }

     // Now check whether the given cell is
     // contained in one of the selected rows
     // (unless we are in column selection mode).
     if ( m_selectionMode != wxGrid::wxGridSelectColumns )
     {
         size_t count = m_rowSelection.GetCount();
         for ( size_t n = 0; n < count; n++ )
         {
             if ( row == m_rowSelection[n] )
               return TRUE;
         }
     }

     // Now check whether the given cell is
     // contained in one of the selected columns
     // (unless we are in row selection mode).
     if ( m_selectionMode != wxGrid::wxGridSelectRows )
     {
         size_t count = m_colSelection.GetCount();
         for ( size_t n = 0; n < count; n++ )
         {
             if ( col == m_colSelection[n] )
               return TRUE;
         }
     }
     return FALSE;
 }

 // Change the selection mode
 void wxGridSelection::SetSelectionMode(wxGrid::wxGridSelectionModes

 {
     // if selection mode is unchanged return immediately
     if (selmode == m_selectionMode)
         return;

     if ( m_selectionMode != wxGrid::wxGridSelectCells )
     {
         // if changing form row to column selection
         // or vice versa, clear the selection.
         if ( selmode != wxGrid::wxGridSelectCells )
             ClearSelection();

         m_selectionMode = selmode;
     }
     else
     {
         // if changing from cell selection to something else,
         // promote selected cells/blocks to whole rows/columns.
         size_t n;
         while ( ( n = m_cellSelection.GetCount() ) > 0 )
         {
             n--;
             wxGridCellCoords& coords = m_cellSelection[n];
             int row = coords.GetRow();
             int col = coords.GetCol();
             m_cellSelection.RemoveAt(n);
             if (selmode == wxGrid::wxGridSelectRows)
                 SelectRow( row );
             else // selmode == wxGridSelectColumns)
                 SelectCol( col );
         }

         for (n = 0; n < m_blockSelectionTopLeft.GetCount(); n++)
         // Note that m_blockSelectionTopLeft's size may be changing!
         {
             wxGridCellCoords& coords = m_blockSelectionTopLeft[n];
             int topRow = coords.GetRow();
             int leftCol = coords.GetCol();
             coords = m_blockSelectionBottomRight[n];
             int bottomRow = coords.GetRow();
             int rightCol = coords.GetCol();
             if (selmode == wxGrid::wxGridSelectRows)
             {
                 if (leftCol != 0 || rightCol != m_grid->GetNumberCols() -

                 {
                     m_blockSelectionTopLeft.RemoveAt(n);
                     m_blockSelectionBottomRight.RemoveAt(n);
                     SelectBlock( topRow, 0,
                                  bottomRow, m_grid->GetNumberCols() - 1,
                                  FALSE, FALSE, FALSE, FALSE, FALSE );
                 }
             }
             else // selmode == wxGridSelectColumns)
             {
                 if (topRow != 0 || bottomRow != m_grid->GetNumberRows() -

                 {
                     m_blockSelectionTopLeft.RemoveAt(n);
                     m_blockSelectionBottomRight.RemoveAt(n);
                     SelectBlock( 0, leftCol,
                                  m_grid->GetNumberRows() - 1, rightCol,
                                  FALSE, FALSE, FALSE, FALSE, FALSE );
                 }
             }
         }
         m_selectionMode = selmode;
     }
 }

 void wxGridSelection::SelectRow( int row,
                                  bool ControlDown,  bool ShiftDown,
                                  bool AltDown, bool MetaDown )
 {
     if ( m_selectionMode == wxGrid::wxGridSelectColumns )
         return;
     size_t count, n;

     // Remove single cells contained in newly selected block.
     if ( m_selectionMode == wxGrid::wxGridSelectCells )
     {
         count = m_cellSelection.GetCount();
         for ( n = 0; n < count; n++ )
         {
             wxGridCellCoords& coords = m_cellSelection[n];
             if ( BlockContainsCell( row, 0, row, m_grid->GetNumberCols() -

                                     coords.GetRow(), coords.GetCol() ) )
             {
                 m_cellSelection.RemoveAt(n);
                 n--; count--;
             }
         }
     }

     // Simplify list of selected blocks (if possible)
     count = m_blockSelectionTopLeft.GetCount();
     bool done = FALSE;
     for ( n = 0; n < count; n++ )
     {
         wxGridCellCoords& coords1 = m_blockSelectionTopLeft[n];
         wxGridCellCoords& coords2 = m_blockSelectionBottomRight[n];

         // Remove block if it is a subset of the row
         if ( coords1.GetRow() == row && row == coords2.GetRow() )
         {
             m_blockSelectionTopLeft.RemoveAt(n);
             m_blockSelectionBottomRight.RemoveAt(n);
             n--; count--;
         }
         else if ( coords1.GetCol() == 0  &&
                   coords2.GetCol() == m_grid->GetNumberCols() - 1 )
         {
             // silently return, if row is contained in block
             if ( coords1.GetRow() <= row && row <= coords2.GetRow() )
                 return;
             // expand block, if it touched row
             else if ( coords1.GetRow() == row + 1)
             {
                 coords1.SetRow(row);
                 done = TRUE;
             }
             else if ( coords2.GetRow() == row - 1)
             {
                 coords2.SetRow(row);
                 done = TRUE;
             }
         }
     }

     // Unless we successfully handled the row,
     // check whether row is already selected.
     if ( !done )
     {
         count = m_rowSelection.GetCount();
         for ( n = 0; n < count; n++ )
         {
             if ( row == m_rowSelection[n] )
                 return;
         }

         // Add row to selection
         m_rowSelection.Add(row);
     }

     // Update View:
     wxRect r = m_grid->BlockToDeviceRect( wxGridCellCoords( row, 0 ),
                                           wxGridCellCoords( row,

     if ( !m_grid->GetBatchCount() )
         ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r );

     // Send Event
     wxGridRangeSelectEvent gridEvt( m_grid->GetId(),
                                     wxEVT_GRID_RANGE_SELECT,
                                     m_grid,
                                     wxGridCellCoords( row, 0 ),
                                     wxGridCellCoords( row,

                                     TRUE,
                                     ControlDown,  ShiftDown,
                                     AltDown, MetaDown );

     m_grid->GetEventHandler()->ProcessEvent(gridEvt);
 }

 void wxGridSelection::SelectCol( int col,
                                  bool ControlDown,  bool ShiftDown,
                                  bool AltDown, bool MetaDown )
 {
     if ( m_selectionMode == wxGrid::wxGridSelectRows )
         return;
     size_t count, n;

     // Remove single cells contained in newly selected block.
     if ( m_selectionMode == wxGrid::wxGridSelectCells )
     {
         count = m_cellSelection.GetCount();
         for ( n = 0; n < count; n++ )
         {
             wxGridCellCoords& coords = m_cellSelection[n];
             if ( BlockContainsCell( 0, col, m_grid->GetNumberRows() - 1,

                                     coords.GetRow(), coords.GetCol() ) )
             {
                 m_cellSelection.RemoveAt(n);
                 n--; count--;
             }
         }
     }

     // Simplify list of selected blocks (if possible)
     count = m_blockSelectionTopLeft.GetCount();
     bool done = FALSE;
     for ( n = 0; n < count; n++ )
     {
         wxGridCellCoords& coords1 = m_blockSelectionTopLeft[n];
         wxGridCellCoords& coords2 = m_blockSelectionBottomRight[n];

         // Remove block if it is a subset of the column
         if ( coords1.GetCol() == col && col == coords2.GetCol() )
         {
             m_blockSelectionTopLeft.RemoveAt(n);
             m_blockSelectionBottomRight.RemoveAt(n);
             n--; count--;
         }
         else if ( coords1.GetRow() == 0  &&
                   coords2.GetRow() == m_grid->GetNumberRows() - 1 )
         {
             // silently return, if row is contained in block
             if ( coords1.GetCol() <= col && col <= coords2.GetCol() )
                 return;
             // expand block, if it touched col
             else if ( coords1.GetCol() == col + 1)
             {
                 coords1.SetCol(col);
                 done = TRUE;
             }
             else if ( coords2.GetCol() == col - 1)
             {
                 coords2.SetCol(col);
                 done = TRUE;
             }
         }
     }

     // Unless we successfully handled the column,
     // Check whether col is already selected.
     if ( !done )
     {
         count = m_colSelection.GetCount();
         for ( n = 0; n < count; n++ )
         {
             if ( col == m_colSelection[n] )
                 return;
         }

         // Add col to selection
         m_colSelection.Add(col);
     }

     // Update View:
     wxRect r = m_grid->BlockToDeviceRect( wxGridCellCoords( 0, col ),
                                           wxGridCellCoords(

     if ( !m_grid->GetBatchCount() )
         ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r );

     // Send Event
     wxGridRangeSelectEvent gridEvt( m_grid->GetId(),
                                     wxEVT_GRID_RANGE_SELECT,
                                     m_grid,
                                     wxGridCellCoords( 0, col ),
                                     wxGridCellCoords(

                                     TRUE,
                                     ControlDown,  ShiftDown,
                                     AltDown, MetaDown );

     m_grid->GetEventHandler()->ProcessEvent(gridEvt);
 }

 void wxGridSelection::SelectBlock( int topRow, int leftCol,
                                    int bottomRow, int rightCol,
                                    bool ControlDown, bool ShiftDown,
                                    bool AltDown, bool MetaDown,
                                    bool sendEvent )
 {
     // Fix the coordinates of the block if needed.
     if ( m_selectionMode == wxGrid::wxGridSelectRows )
     {
         leftCol = 0;
         rightCol = m_grid->GetNumberCols() - 1;
     }
     else if ( m_selectionMode == wxGrid::wxGridSelectColumns )
     {
         topRow = 0;
         bottomRow = m_grid->GetNumberRows() - 1;
     }
     if ( topRow > bottomRow )
     {
         int temp = topRow;
         topRow = bottomRow;
         bottomRow = temp;
     }

     if ( leftCol > rightCol )
     {
         int temp = leftCol;
         leftCol = rightCol;
         rightCol = temp;
     }

     // Handle single cell selection in SelectCell.
     // (MB: added check for selection mode here to prevent
     //  crashes if, for example, we are select rows and the
     //  grid only has 1 col)
     if ( m_selectionMode == wxGrid::wxGridSelectCells &&
          topRow == bottomRow && leftCol == rightCol )
         SelectCell( topRow, leftCol, ControlDown,  ShiftDown,
                     AltDown, MetaDown, sendEvent );

     size_t count, n;
     // Remove single cells contained in newly selected block.
     if ( m_selectionMode == wxGrid::wxGridSelectCells )
     {
         count = m_cellSelection.GetCount();
         for ( n = 0; n < count; n++ )
         {
             wxGridCellCoords& coords = m_cellSelection[n];
             if ( BlockContainsCell( topRow, leftCol, bottomRow, rightCol,
                                     coords.GetRow(), coords.GetCol() ) )
             {
                 m_cellSelection.RemoveAt(n);
                 n--; count--;
             }
         }
     }

     // If a block containing the selection is already selected, return,
     // if a block contained in the selection is found, remove it.

     count = m_blockSelectionTopLeft.GetCount();
     for ( n = 0; n < count; n++ )
     {
         wxGridCellCoords& coords1 = m_blockSelectionTopLeft[n];
         wxGridCellCoords& coords2 = m_blockSelectionBottomRight[n];
         switch ( BlockContain( coords1.GetRow(), coords1.GetCol(),
                                coords2.GetRow(), coords2.GetCol(),
                                topRow, leftCol, bottomRow, rightCol ) )
         {
           case 1:
             return;
           case -1:
             m_blockSelectionTopLeft.RemoveAt(n);
             m_blockSelectionBottomRight.RemoveAt(n);
             n--; count--;
           default:
             ;
         }
     }

     // If a row containing the selection is already selected, return,
     // if a row contained in newly selected block is found, remove it.
     if ( m_selectionMode != wxGrid::wxGridSelectColumns )
     {
         count = m_rowSelection.GetCount();
         for ( n = 0; n < count; n++ )
         {
             switch ( BlockContain( m_rowSelection[n], 0,
                                    m_rowSelection[n],

                                    topRow, leftCol, bottomRow,

             {
               case 1:
                 return;
               case -1:
                 m_rowSelection.RemoveAt(n);
                 n--; count--;
               default:
                 ;
             }
         }
     }
     if ( m_selectionMode != wxGrid::wxGridSelectRows )
     {
         count = m_colSelection.GetCount();
         for ( n = 0; n < count; n++ )
         {
             switch ( BlockContain( 0, m_colSelection[n],
                                    m_grid->GetNumberRows()-1,

                                    topRow, leftCol, bottomRow,

             {
               case 1:
                 return;
               case -1:
                 m_colSelection.RemoveAt(n);
                 n--; count--;
               default:
                 ;
             }
         }
     }
     m_blockSelectionTopLeft.Add( wxGridCellCoords( topRow, leftCol ) );
     m_blockSelectionBottomRight.Add( wxGridCellCoords( bottomRow,

     // Update View:
     wxRect r = m_grid->BlockToDeviceRect( wxGridCellCoords( topRow, leftCo

                                           wxGridCellCoords( bottomRow,

     if ( !m_grid->GetBatchCount() )
         ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r );

     // Send Event, if not disabled.
     if ( sendEvent )
     {
         wxGridRangeSelectEvent gridEvt( m_grid->GetId(),
                                         wxEVT_GRID_RANGE_SELECT,
                                         m_grid,
                                         wxGridCellCoords( topRow,

                                         wxGridCellCoords( bottomRow,

                                         TRUE,
                                         ControlDown, ShiftDown,
                                         AltDown, MetaDown );
         m_grid->GetEventHandler()->ProcessEvent(gridEvt);
     }
 }

 void wxGridSelection::SelectCell( int row, int col,
                                   bool ControlDown, bool ShiftDown,
                                   bool AltDown, bool MetaDown,
                                   bool sendEvent )
 {
     if ( m_selectionMode == wxGrid::wxGridSelectRows )
     {
         SelectBlock(row, 0, row, m_grid->GetNumberCols() - 1,
                     ControlDown, ShiftDown, AltDown, MetaDown, sendEvent);
         return;
     }
     else if ( m_selectionMode == wxGrid::wxGridSelectColumns )
     {
         SelectBlock(0, col, m_grid->GetNumberRows() - 1, col,
                     ControlDown, ShiftDown, AltDown, MetaDown, sendEvent);
         return;
     }
     else if ( IsInSelection ( row, col ) )
         return;
     m_cellSelection.Add( wxGridCellCoords( row, col ) );

     // Update View:
     wxRect r = m_grid->BlockToDeviceRect( wxGridCellCoords( row, col ),
                                           wxGridCellCoords( row, col ) );
     if ( !m_grid->GetBatchCount() )
         ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r );

     // Send event
     if (sendEvent)
     {
         wxGridRangeSelectEvent gridEvt( m_grid->GetId(),
                                         wxEVT_GRID_RANGE_SELECT,
                                         m_grid,
                                         wxGridCellCoords( row, col ),
                                         wxGridCellCoords( row, col ),
                                         TRUE,
                                         ControlDown, ShiftDown,
                                         AltDown, MetaDown);
         m_grid->GetEventHandler()->ProcessEvent(gridEvt);
     }
 }

 void wxGridSelection::ToggleCellSelection( int row, int col,
                                            bool ControlDown, bool

                                            bool AltDown, bool MetaDown )
 {
     // if the cell is not selected, select it
     if ( !IsInSelection ( row, col ) )
     {
         SelectCell( row, col, ControlDown, ShiftDown,
                     AltDown, MetaDown );
         return;
     }

     // otherwise deselect it. This can be simple or more or
     // less difficult, depending on how the cell is selected.
     size_t count, n;

     // The simplest case: The cell is contained in m_cellSelection
     // Then it can't be contained in rows/cols/block (since those
     // would remove the cell from m_cellSelection on creation), so
     // we just have to remove it from m_cellSelection.

     if ( m_selectionMode == wxGrid::wxGridSelectCells )
     {
         count = m_cellSelection.GetCount();
         for ( n = 0; n < count; n++ )
         {
             wxGridCellCoords& coords = m_cellSelection[n];
             if ( row == coords.GetRow() && col == coords.GetCol() )
             {
                 wxRect r;
                 r = m_grid->BlockToDeviceRect( m_cellSelection[n],
                                                m_cellSelection[n] );
                 m_cellSelection.RemoveAt(n);
                 n--; count--;
                 if ( !m_grid->GetBatchCount() )
                     ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r );

                 // Send event
                 wxGridRangeSelectEvent gridEvt( m_grid->GetId(),
                                                 wxEVT_GRID_RANGE_SELECT,
                                                 m_grid,
                                                 wxGridCellCoords( row,

                                                 wxGridCellCoords( row,

                                                 FALSE,
                                                 ControlDown, ShiftDown,
                                                 AltDown, MetaDown );
                 m_grid->GetEventHandler()->ProcessEvent(gridEvt);
                 return;
             }
         }
     }

     // The most difficult case: The cell is member of one or even several
     // blocks. Split each such block in up to 4 new parts, that don't
     // contain the cell to be selected, like this:
     // |---------------------------|
     // |                           |
     // |           part 1          |
     // |                           |
     // |---------------------------|
     // |   part 3   |x|   part 4   |
     // |---------------------------|
     // |                           |
     // |           part 2          |
     // |                           |
     // |---------------------------|
     //   (The x marks the newly deselected cell).
     // Note: in row selection mode, we only need part1 and part2;
     //       in column selection mode, we only need part 3 and part4,
     //          which are expanded to whole columns automatically!

     count = m_blockSelectionTopLeft.GetCount();
     for ( n = 0; n < count; n++ )
       {
         wxGridCellCoords& coords1 = m_blockSelectionTopLeft[n];
         wxGridCellCoords& coords2 = m_blockSelectionBottomRight[n];
         int topRow = coords1.GetRow();
         int leftCol = coords1.GetCol();
         int bottomRow = coords2.GetRow();
         int rightCol = coords2.GetCol();
         if ( BlockContainsCell( topRow, leftCol, bottomRow, rightCol,
                                 row, col ) )
         {
             // remove the block
             m_blockSelectionTopLeft.RemoveAt(n);
             m_blockSelectionBottomRight.RemoveAt(n);
             n--; count--;
             // add up to 4 smaller blocks and set update region
             if ( m_selectionMode != wxGrid::wxGridSelectColumns )
             {
                 if ( topRow < row )
                     SelectBlock( topRow, leftCol, row - 1, rightCol,
 FALSE, FALSE, FALSE, FALSE, FALSE );
                 if ( bottomRow > row )
                     SelectBlock( row + 1, leftCol, bottomRow, rightCol,
 FALSE, FALSE, FALSE, FALSE, FALSE );
             }
             if ( m_selectionMode != wxGrid::wxGridSelectRows )
             {
                 if ( leftCol < col )
                     SelectBlock( row, leftCol, row, col - 1,
 FALSE, FALSE, FALSE, FALSE, FALSE );
                 if ( rightCol > col )
                     SelectBlock( row, col + 1, row, rightCol,
 FALSE, FALSE, FALSE, FALSE, FALSE );
             }
         }
     }

     // remove a cell from a row, adding up to two new blocks
     if ( m_selectionMode != wxGrid::wxGridSelectColumns )
     {
         count = m_rowSelection.GetCount();
         for ( n = 0; n < count; n++ )
         {
             if ( m_rowSelection[n] == row )
             {
                 m_rowSelection.RemoveAt(n);
                 n--; count--;
                 if (m_selectionMode == wxGrid::wxGridSelectCells)
                 {
                     if ( col > 0 )
                         SelectBlock( row, 0, row, col - 1,
      FALSE, FALSE, FALSE, FALSE, FALSE );
                     if ( col < m_grid->GetNumberCols() - 1 )
                         SelectBlock( row, col + 1,
                                      row, m_grid->GetNumberCols() - 1,
                                      FALSE, FALSE, FALSE, FALSE, FALSE );
                 }
             }
         }
     }

     // remove a cell from a column, adding up to two new blocks
     if ( m_selectionMode != wxGrid::wxGridSelectRows )
     {
         count = m_colSelection.GetCount();
         for ( n = 0; n < count; n++ )
         {
             if ( m_colSelection[n] == col )
             {
                 m_colSelection.RemoveAt(n);
                 n--; count--;
                 if (m_selectionMode == wxGrid::wxGridSelectCells)
                 {
                     if ( row > 0 )
                         SelectBlock( 0, col, row - 1, col,
      FALSE, FALSE, FALSE, FALSE, FALSE );
                     if ( row < m_grid->GetNumberRows() - 1 )
                         SelectBlock( row + 1, col,
                                      m_grid->GetNumberRows() - 1, col,
                                      FALSE, FALSE, FALSE, FALSE, FALSE );
                 }
             }
         }
     }

     // Refresh the screen and send the event; according to

     // we need to either update only the cell, or the whole row/column.
     wxRect r;
     switch (m_selectionMode)
     {
       case wxGrid::wxGridSelectCells:
       {
           r = m_grid->BlockToDeviceRect( wxGridCellCoords( row, col ),
                                          wxGridCellCoords( row, col ) );
           if ( !m_grid->GetBatchCount() )
               ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r );
           wxGridRangeSelectEvent gridEvt( m_grid->GetId(),
                                           wxEVT_GRID_RANGE_SELECT,
                                           m_grid,
                                           wxGridCellCoords( row, col ),
                                           wxGridCellCoords( row, col ),
                                           FALSE,
                                           ControlDown, ShiftDown,
                                           AltDown, MetaDown );
           m_grid->GetEventHandler()->ProcessEvent(gridEvt);
           break;
       }
       case wxGrid::wxGridSelectRows:
       {
           r = m_grid->BlockToDeviceRect( wxGridCellCoords( row, 0 ),
                                          wxGridCellCoords( row,

           if ( !m_grid->GetBatchCount() )
               ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r );
           wxGridRangeSelectEvent gridEvt( m_grid->GetId(),
                                           wxEVT_GRID_RANGE_SELECT,
                                           m_grid,
                                           wxGridCellCoords( row, 0 ),
                                           wxGridCellCoords( row,

                                           FALSE,
                                           ControlDown, ShiftDown,
                                           AltDown, MetaDown );
           m_grid->GetEventHandler()->ProcessEvent(gridEvt);
           break;
       }
       case wxGrid::wxGridSelectColumns:
       {
           r = m_grid->BlockToDeviceRect( wxGridCellCoords( 0, col ),
                                          wxGridCellCoords(

           if ( !m_grid->GetBatchCount() )
               ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r );
           wxGridRangeSelectEvent gridEvt( m_grid->GetId(),
                                           wxEVT_GRID_RANGE_SELECT,
                                           m_grid,
                                           wxGridCellCoords( 0, col ),
                                           wxGridCellCoords(

                                           FALSE,
                                           ControlDown, ShiftDown,
                                           AltDown, MetaDown );
           m_grid->GetEventHandler()->ProcessEvent(gridEvt);
           break;
       }
     }
 }

 void wxGridSelection::ClearSelection()
 {
     size_t n;

     // deselect all invidiual cells and update the screen
     if ( m_selectionMode == wxGrid::wxGridSelectCells )
     {

         while( ( n = m_cellSelection.GetCount() ) > 0)
         {
             wxRect r;
             n--;
             r = m_grid->BlockToDeviceRect( m_cellSelection[n],
                                            m_cellSelection[n] );
             m_cellSelection.RemoveAt(n);
             if ( !m_grid->GetBatchCount() )
                 ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r );
         }
     }

     // deselect all blocks and update the screen
     while( ( n = m_blockSelectionTopLeft.GetCount() ) > 0)
     {
         wxRect r;
         n--;
         r = m_grid->BlockToDeviceRect( m_blockSelectionTopLeft[n],
                                        m_blockSelectionBottomRight[n] );
         m_blockSelectionTopLeft.RemoveAt(n);
         m_blockSelectionBottomRight.RemoveAt(n);
         if ( !m_grid->GetBatchCount() )
             ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r );
     }

     // deselect all rows and update the screen
     if ( m_selectionMode != wxGrid::wxGridSelectColumns )
     {
         while( ( n = m_rowSelection.GetCount() ) > 0)
         {
             n--;
             int & row = m_rowSelection[n];
             wxRect r;
             r = m_grid->BlockToDeviceRect( wxGridCellCoords( row, 0 ),
                                            wxGridCellCoords( row,

             m_rowSelection.RemoveAt(n);
             if ( !m_grid->GetBatchCount() )
                 ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r );
         }
     }

     // deselect all columns and update the screen
     if ( m_selectionMode != wxGrid::wxGridSelectRows )
     {
         while( ( n = m_colSelection.GetCount() ) > 0)
         {
             n--;
             int & col = m_colSelection[n];
             wxRect r;
             r = m_grid->BlockToDeviceRect( wxGridCellCoords( 0, col ),
                                            wxGridCellCoords(

             m_colSelection.RemoveAt(n);
             if ( !m_grid->GetBatchCount() )
                 ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r );
         }
     }

     // One deselection event, indicating deselection of _all_ cells.
     // (No finer grained events for each of the smaller regions
     //  deselected above!)
     wxGridRangeSelectEvent gridEvt( m_grid->GetId(),
                                     wxEVT_GRID_RANGE_SELECT,
                                     m_grid,
                                     wxGridCellCoords( 0, 0 ),
                                     wxGridCellCoords(


                                     FALSE );

     m_grid->GetEventHandler()->ProcessEvent(gridEvt);
 }


 void wxGridSelection::UpdateRows( size_t pos, int numRows )
 {
     size_t count = m_cellSelection.GetCount();
     size_t n;
     for ( n = 0; n < count; n++ )
     {
         wxGridCellCoords& coords = m_cellSelection[n];
         wxCoord row = coords.GetRow();
         if ((size_t)row >= pos)
         {
             if (numRows > 0)
             {
                 // If rows inserted, increase row counter where necessary
                 coords.SetRow(row + numRows);
             }
             else if (numRows < 0)
             {
                 // If rows deleted ...
                 if ((size_t)row >= pos - numRows)
                 {
                     // ...either decrement row counter (if row still

                     coords.SetRow(row + numRows);
                 }
                 else
                 {
                     // ...or remove the attribute
                     m_cellSelection.RemoveAt(n);
                     n--; count--;
                 }
             }
         }
     }

     count = m_blockSelectionTopLeft.GetCount();
     for ( n = 0; n < count; n++ )
     {
         wxGridCellCoords& coords1 = m_blockSelectionTopLeft[n];
         wxGridCellCoords& coords2 = m_blockSelectionBottomRight[n];
         wxCoord row1 = coords1.GetRow();
         wxCoord row2 = coords2.GetRow();
         if ((size_t)row2 >= pos)
         {
             if (numRows > 0)
             {
                 // If rows inserted, increase row counter where necessary
                 coords2.SetRow(row2 + numRows);
                 if ( (size_t)row1 >= pos )
                     coords1.SetRow(row1 + numRows);
             }
             else if (numRows < 0)
             {
                 // If rows deleted ...
                 if ((size_t)row2 >= pos - numRows)
                 {
                     // ...either decrement row counter (if row still

                     coords2.SetRow(row2 + numRows);
                     if ( (size_t) row1 >= pos)
                         coords1.SetRow( wxMax(row1 + numRows, (int)

                 }
                 else
                 {
                     if ( (size_t) row1 >= pos)
                     {
                         // ...or remove the attribute
                         m_blockSelectionTopLeft.RemoveAt(n);
                         m_blockSelectionBottomRight.RemoveAt(n);
                         n--; count--;
                     }
                     else
                         coords2.SetRow(pos);
                 }
             }
         }
     }

     count = m_rowSelection.GetCount();
     for ( n = 0; n < count; n++ )
     {
 #if ( __DMC__ < 0x835 )
         int & rowOrCol = m_rowSelection[n];
         if ( (size_t)rowOrCol >= pos )
         {
             if ( numRows > 0 )
             {
                 // If rows inserted, include row counter where necessary
                 rowOrCol += numRows;
             }
             else if ( numRows < 0)
             {
                 // If rows deleted, either decrement row counter (if row

                 if ((size_t)rowOrCol >= pos - numRows)
                     rowOrCol += numRows;
                 else
                 {
                     m_rowSelection.RemoveAt(n);
                     n--; count--;
                 }
             }
         }
 #else
 #pragma message ( "DMC: alternate implementation due to problems with DMC

       int  rowOrCol_ = m_rowSelection [ n ];

       if ( ( size_t ) rowOrCol_ >= pos )
       {
           if ( numRows > 0 )
           {
               m_rowSelection [ n ] += numRows;
           }
           else if ( numRows < 0 )
           {
               if ( ( size_t ) rowOrCol_ >= ( pos - numRows ) )
                   m_rowSelection [ n ] += numRows;
               else
               {
                   m_rowSelection.RemoveAt ( n );
                   n--;
                   count--;
               }
           }
       }
 #endif
     }
     // No need to touch selected columns, unless we removed _all_
     // rows, in this case, we remove all columns from the selection.

     if ( !m_grid->GetNumberRows() )
         m_colSelection.Clear();
 }


 void wxGridSelection::UpdateCols( size_t pos, int numCols )
 {
     size_t count = m_cellSelection.GetCount();
     size_t n;
     for ( n = 0; n < count; n++ )
     {
         wxGridCellCoords& coords = m_cellSelection[n];
         wxCoord col = coords.GetCol();
         if ((size_t)col >= pos)
         {
             if (numCols > 0)
             {
                 // If rows inserted, increase row counter where necessary
                 coords.SetCol(col + numCols);
             }
             else if (numCols < 0)
             {
                 // If rows deleted ...
                 if ((size_t)col >= pos - numCols)
                 {
                     // ...either decrement row counter (if row still

                     coords.SetCol(col + numCols);
                 }
                 else
                 {
                     // ...or remove the attribute
                     m_cellSelection.RemoveAt(n);
                     n--; count--;
                 }
             }
         }
     }

     count = m_blockSelectionTopLeft.GetCount();
     for ( n = 0; n < count; n++ )
     {
         wxGridCellCoords& coords1 = m_blockSelectionTopLeft[n];
         wxGridCellCoords& coords2 = m_blockSelectionBottomRight[n];
         wxCoord col1 = coords1.GetCol();
         wxCoord col2 = coords2.GetCol();
         if ((size_t)col2 >= pos)
         {
             if (numCols > 0)
             {
                 // If rows inserted, increase row counter where necessary
                 coords2.SetCol(col2 + numCols);
                 if ( (size_t)col1 >= pos )
                     coords1.SetCol(col1 + numCols);
             }
             else if (numCols < 0)
             {
                 // If cols deleted ...
                 if ((size_t)col2 >= pos - numCols)
                 {
                     // ...either decrement col counter (if col still

                     coords2.SetCol(col2 + numCols);
                     if ( (size_t) col1 >= pos)
                         coords1.SetCol( wxMax(col1 + numCols, (int)

                 }
                 else
                 {
                     if ( (size_t) col1 >= pos)
                     {
                         // ...or remove the attribute
                         m_blockSelectionTopLeft.RemoveAt(n);
                         m_blockSelectionBottomRight.RemoveAt(n);
                         n--; count--;
                     }
                     else
                         coords2.SetCol(pos);
                 }
             }
         }
     }

     count = m_colSelection.GetCount();
     for ( n = 0; n < count; n++ )
     {
 #if ( __DMC__ < 0x835 )
         int & rowOrCol = m_colSelection[n];
         if ( (size_t)rowOrCol >= pos )
         {
             if ( numCols > 0 )
             {
                 // If cols inserted, include col counter where necessary
                 rowOrCol += numCols;
             }
             else if ( numCols < 0)
             {
                 // If cols deleted, either decrement col counter (if col

                 if ((size_t)rowOrCol >= pos - numCols)
                     rowOrCol += numCols;
                 else
                 {
                     m_colSelection.RemoveAt(n);
                     n--; count--;
                 }
             }
         }
 #else
 #pragma message ( "DMC: alternate implementation due to problems with DMC

         int   rowOrCol = m_colSelection [ n ];
         if ( ( size_t ) rowOrCol >= pos )
         {
             if ( numCols > 0 )
                 m_colSelection [ n ] += numCols;
             else if ( numCols < 0 )
             {
                 if ( ( size_t ) rowOrCol >= ( pos -numCols ) )
                     m_colSelection [ n ] += numCols;
                 else
                 {
                     m_colSelection.RemoveAt ( n );
                     n--;
                     count--;
                 }
             }
         }
 #endif
     }

     // No need to touch selected rows, unless we removed _all_
     // columns, in this case, we remove all rows from the selection.
     if ( !m_grid->GetNumberCols() )
         m_rowSelection.Clear();
 }


 int wxGridSelection::BlockContain( int topRow1, int leftCol1,
                                    int bottomRow1, int rightCol1,
                                    int topRow2, int leftCol2,
                                    int bottomRow2, int rightCol2 )
 // returns 1, if Block1 contains Block2,
 //        -1, if Block2 contains Block1,
 //         0, otherwise
 {
     if ( topRow1 <= topRow2 && bottomRow2 <= bottomRow1 &&
          leftCol1 <= leftCol2 && rightCol2 <= rightCol1 )
         return 1;
     else if ( topRow2 <= topRow1 && bottomRow1 <= bottomRow2 &&
               leftCol2 <= leftCol1 && rightCol1 <= rightCol2 )
         return -1;
     return 0;
 }

 #endif

Aug 25 2003
prev sibling parent "chris elliott" <biol75 york.ac.uk> writes:
Fixes for 8.35 applied to CVS (Head and 2.4 branch) - thanks to Arjan for
the suggested changes!

chris

"Arjan Knepper" <arjan ask.me> wrote in message
news:bie115$28vl$1 digitaldaemon.com...
 Walter,

 Any suggestions how to isolate such errors?

 I have isolated two identical blocks of code in two separated member
 functions causing this error, but tearing it apart into a new file,
 makes the error disappear.

 The strange thing is when I comment the first code block out the error
 355 still occurs in the second code block, but changing the first code
 block a little makes also the error disappear for the _unmodified_
 second block of code.

 attached the file.

 p.s. This file could also be used as work around for DMC 8.35 and
 wxWindows-2.4.1 and the current cvs.


 Arjan

 chris elliott wrote:

 this release still has a bug compiling current wxWindows source (it was
 ok in 8.34)

 dmc -c -cpp -Ae -Ar -mn -D_WINDOWS -6 -a8 -Nc -c -H -HD..\..\d_mars -HO-
 -DWXMSW
  -D__WIN32__ -D__WIN95__ -D__WXDEBUG__  -I..\..\include -I..\..\lib\_sc
 -I..\..\
 contrib\include
 -I..\../src/regex;..\../src/png;..\../src/jpeg;..\../src/zlib;..
 \../src/tiff


 Internal error: type 355
 --- errorlevel 1


 D:\wx\wxWindows\src\msw>scppn
 Digital Mars C/C++ Compiler Version 8.35.10n
 Copyright (C) Digital Mars 2000-2003.  All Rights Reserved.
 Written by Walter Bright
 www.digitalmars.com

 chris

 Walter wrote:

 An accummulation of a lot of minor fixes. Now has STLSoft 1.6.5.

 http://www.digitalmars.com/compiler.htm



---------------------------------------------------------------------------- ----

 // Name:        generic/gridsel.cpp
 // Purpose:     wxGridSelection
 // Author:      Stefan Neis
 // Modified by:
 // Created:     20/02/1999
 // RCS-ID:      $Id: gridsel.cpp,v 1.1.1.1 2003/08/14 11:51:46 arjan Exp $
 // Copyright:   (c) Stefan Neis (Stefan.Neis t-online.de)
 // Licence:     wxWindows licence

/
 //

 // declarations
 //


---
 // headers

---
 #ifdef __GNUG__
     #pragma implementation "gridsel.h"
 #endif

 // For compilers that support precompilation, includes "wx/wx.h".
 #include "wx/wxprec.h"

 #include "wx/defs.h"

 #ifdef __BORLANDC__
     #pragma hdrstop
 #endif

 #if defined(wxUSE_NEW_GRID) && (wxUSE_NEW_GRID)

 #include "wx/generic/gridsel.h"

 // Some explanation for the members of the class:
 // m_cellSelection stores individual selected cells
 //   -- this is only used if m_selectionMode == wxGridSelectCells
 // m_blockSelectionTopLeft and m_blockSelectionBottomRight
 //   store the upper left and lower right corner of selected Blocks
 // m_rowSelection and m_colSelection store individual selected
 //   rows and columns; maybe those are superfluous and should be
 //   treated as blocks?

 wxGridSelection::wxGridSelection( wxGrid * grid,
                                   wxGrid::wxGridSelectionModes sel )
 {
     m_grid = grid;
     m_selectionMode = sel;
 }

 bool wxGridSelection::IsSelection()
 {
   return ( m_cellSelection.GetCount() ||

            m_rowSelection.GetCount() || m_colSelection.GetCount() );
 }

 bool wxGridSelection::IsInSelection ( int row, int col )
 {
     size_t count;

     // First check whether the given cell is individually selected
     // (if m_selectionMode is wxGridSelectCells).
     if ( m_selectionMode == wxGrid::wxGridSelectCells )
     {
         count = m_cellSelection.GetCount();
         for ( size_t n = 0; n < count; n++ )
         {
             wxGridCellCoords& coords = m_cellSelection[n];
             if ( row == coords.GetRow() && col == coords.GetCol() )
                 return TRUE;
         }
     }

     // Now check whether the given cell is
     // contained in one of the selected blocks.
     count = m_blockSelectionTopLeft.GetCount();
     for ( size_t n = 0; n < count; n++ )
     {
         wxGridCellCoords& coords1 = m_blockSelectionTopLeft[n];
         wxGridCellCoords& coords2 = m_blockSelectionBottomRight[n];
         if ( BlockContainsCell(coords1.GetRow(), coords1.GetCol(),
                                coords2.GetRow(), coords2.GetCol(),
                                row, col ) )
             return TRUE;
     }

     // Now check whether the given cell is
     // contained in one of the selected rows
     // (unless we are in column selection mode).
     if ( m_selectionMode != wxGrid::wxGridSelectColumns )
     {
         size_t count = m_rowSelection.GetCount();
         for ( size_t n = 0; n < count; n++ )
         {
             if ( row == m_rowSelection[n] )
               return TRUE;
         }
     }

     // Now check whether the given cell is
     // contained in one of the selected columns
     // (unless we are in row selection mode).
     if ( m_selectionMode != wxGrid::wxGridSelectRows )
     {
         size_t count = m_colSelection.GetCount();
         for ( size_t n = 0; n < count; n++ )
         {
             if ( col == m_colSelection[n] )
               return TRUE;
         }
     }
     return FALSE;
 }

 // Change the selection mode
 void wxGridSelection::SetSelectionMode(wxGrid::wxGridSelectionModes

 {
     // if selection mode is unchanged return immediately
     if (selmode == m_selectionMode)
         return;

     if ( m_selectionMode != wxGrid::wxGridSelectCells )
     {
         // if changing form row to column selection
         // or vice versa, clear the selection.
         if ( selmode != wxGrid::wxGridSelectCells )
             ClearSelection();

         m_selectionMode = selmode;
     }
     else
     {
         // if changing from cell selection to something else,
         // promote selected cells/blocks to whole rows/columns.
         size_t n;
         while ( ( n = m_cellSelection.GetCount() ) > 0 )
         {
             n--;
             wxGridCellCoords& coords = m_cellSelection[n];
             int row = coords.GetRow();
             int col = coords.GetCol();
             m_cellSelection.RemoveAt(n);
             if (selmode == wxGrid::wxGridSelectRows)
                 SelectRow( row );
             else // selmode == wxGridSelectColumns)
                 SelectCol( col );
         }

         for (n = 0; n < m_blockSelectionTopLeft.GetCount(); n++)
         // Note that m_blockSelectionTopLeft's size may be changing!
         {
             wxGridCellCoords& coords = m_blockSelectionTopLeft[n];
             int topRow = coords.GetRow();
             int leftCol = coords.GetCol();
             coords = m_blockSelectionBottomRight[n];
             int bottomRow = coords.GetRow();
             int rightCol = coords.GetCol();
             if (selmode == wxGrid::wxGridSelectRows)
             {
                 if (leftCol != 0 || rightCol != m_grid->GetNumberCols() -

                 {
                     m_blockSelectionTopLeft.RemoveAt(n);
                     m_blockSelectionBottomRight.RemoveAt(n);
                     SelectBlock( topRow, 0,
                                  bottomRow, m_grid->GetNumberCols() - 1,
                                  FALSE, FALSE, FALSE, FALSE, FALSE );
                 }
             }
             else // selmode == wxGridSelectColumns)
             {
                 if (topRow != 0 || bottomRow != m_grid->GetNumberRows() -

                 {
                     m_blockSelectionTopLeft.RemoveAt(n);
                     m_blockSelectionBottomRight.RemoveAt(n);
                     SelectBlock( 0, leftCol,
                                  m_grid->GetNumberRows() - 1, rightCol,
                                  FALSE, FALSE, FALSE, FALSE, FALSE );
                 }
             }
         }
         m_selectionMode = selmode;
     }
 }

 void wxGridSelection::SelectRow( int row,
                                  bool ControlDown,  bool ShiftDown,
                                  bool AltDown, bool MetaDown )
 {
     if ( m_selectionMode == wxGrid::wxGridSelectColumns )
         return;
     size_t count, n;

     // Remove single cells contained in newly selected block.
     if ( m_selectionMode == wxGrid::wxGridSelectCells )
     {
         count = m_cellSelection.GetCount();
         for ( n = 0; n < count; n++ )
         {
             wxGridCellCoords& coords = m_cellSelection[n];
             if ( BlockContainsCell( row, 0, row, m_grid->GetNumberCols() -

                                     coords.GetRow(), coords.GetCol() ) )
             {
                 m_cellSelection.RemoveAt(n);
                 n--; count--;
             }
         }
     }

     // Simplify list of selected blocks (if possible)
     count = m_blockSelectionTopLeft.GetCount();
     bool done = FALSE;
     for ( n = 0; n < count; n++ )
     {
         wxGridCellCoords& coords1 = m_blockSelectionTopLeft[n];
         wxGridCellCoords& coords2 = m_blockSelectionBottomRight[n];

         // Remove block if it is a subset of the row
         if ( coords1.GetRow() == row && row == coords2.GetRow() )
         {
             m_blockSelectionTopLeft.RemoveAt(n);
             m_blockSelectionBottomRight.RemoveAt(n);
             n--; count--;
         }
         else if ( coords1.GetCol() == 0  &&
                   coords2.GetCol() == m_grid->GetNumberCols() - 1 )
         {
             // silently return, if row is contained in block
             if ( coords1.GetRow() <= row && row <= coords2.GetRow() )
                 return;
             // expand block, if it touched row
             else if ( coords1.GetRow() == row + 1)
             {
                 coords1.SetRow(row);
                 done = TRUE;
             }
             else if ( coords2.GetRow() == row - 1)
             {
                 coords2.SetRow(row);
                 done = TRUE;
             }
         }
     }

     // Unless we successfully handled the row,
     // check whether row is already selected.
     if ( !done )
     {
         count = m_rowSelection.GetCount();
         for ( n = 0; n < count; n++ )
         {
             if ( row == m_rowSelection[n] )
                 return;
         }

         // Add row to selection
         m_rowSelection.Add(row);
     }

     // Update View:
     wxRect r = m_grid->BlockToDeviceRect( wxGridCellCoords( row, 0 ),
                                           wxGridCellCoords( row,

     if ( !m_grid->GetBatchCount() )
         ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r );

     // Send Event
     wxGridRangeSelectEvent gridEvt( m_grid->GetId(),
                                     wxEVT_GRID_RANGE_SELECT,
                                     m_grid,
                                     wxGridCellCoords( row, 0 ),
                                     wxGridCellCoords( row,

                                     TRUE,
                                     ControlDown,  ShiftDown,
                                     AltDown, MetaDown );

     m_grid->GetEventHandler()->ProcessEvent(gridEvt);
 }

 void wxGridSelection::SelectCol( int col,
                                  bool ControlDown,  bool ShiftDown,
                                  bool AltDown, bool MetaDown )
 {
     if ( m_selectionMode == wxGrid::wxGridSelectRows )
         return;
     size_t count, n;

     // Remove single cells contained in newly selected block.
     if ( m_selectionMode == wxGrid::wxGridSelectCells )
     {
         count = m_cellSelection.GetCount();
         for ( n = 0; n < count; n++ )
         {
             wxGridCellCoords& coords = m_cellSelection[n];
             if ( BlockContainsCell( 0, col, m_grid->GetNumberRows() - 1,

                                     coords.GetRow(), coords.GetCol() ) )
             {
                 m_cellSelection.RemoveAt(n);
                 n--; count--;
             }
         }
     }

     // Simplify list of selected blocks (if possible)
     count = m_blockSelectionTopLeft.GetCount();
     bool done = FALSE;
     for ( n = 0; n < count; n++ )
     {
         wxGridCellCoords& coords1 = m_blockSelectionTopLeft[n];
         wxGridCellCoords& coords2 = m_blockSelectionBottomRight[n];

         // Remove block if it is a subset of the column
         if ( coords1.GetCol() == col && col == coords2.GetCol() )
         {
             m_blockSelectionTopLeft.RemoveAt(n);
             m_blockSelectionBottomRight.RemoveAt(n);
             n--; count--;
         }
         else if ( coords1.GetRow() == 0  &&
                   coords2.GetRow() == m_grid->GetNumberRows() - 1 )
         {
             // silently return, if row is contained in block
             if ( coords1.GetCol() <= col && col <= coords2.GetCol() )
                 return;
             // expand block, if it touched col
             else if ( coords1.GetCol() == col + 1)
             {
                 coords1.SetCol(col);
                 done = TRUE;
             }
             else if ( coords2.GetCol() == col - 1)
             {
                 coords2.SetCol(col);
                 done = TRUE;
             }
         }
     }

     // Unless we successfully handled the column,
     // Check whether col is already selected.
     if ( !done )
     {
         count = m_colSelection.GetCount();
         for ( n = 0; n < count; n++ )
         {
             if ( col == m_colSelection[n] )
                 return;
         }

         // Add col to selection
         m_colSelection.Add(col);
     }

     // Update View:
     wxRect r = m_grid->BlockToDeviceRect( wxGridCellCoords( 0, col ),
                                           wxGridCellCoords(

     if ( !m_grid->GetBatchCount() )
         ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r );

     // Send Event
     wxGridRangeSelectEvent gridEvt( m_grid->GetId(),
                                     wxEVT_GRID_RANGE_SELECT,
                                     m_grid,
                                     wxGridCellCoords( 0, col ),
                                     wxGridCellCoords(

                                     TRUE,
                                     ControlDown,  ShiftDown,
                                     AltDown, MetaDown );

     m_grid->GetEventHandler()->ProcessEvent(gridEvt);
 }

 void wxGridSelection::SelectBlock( int topRow, int leftCol,
                                    int bottomRow, int rightCol,
                                    bool ControlDown, bool ShiftDown,
                                    bool AltDown, bool MetaDown,
                                    bool sendEvent )
 {
     // Fix the coordinates of the block if needed.
     if ( m_selectionMode == wxGrid::wxGridSelectRows )
     {
         leftCol = 0;
         rightCol = m_grid->GetNumberCols() - 1;
     }
     else if ( m_selectionMode == wxGrid::wxGridSelectColumns )
     {
         topRow = 0;
         bottomRow = m_grid->GetNumberRows() - 1;
     }
     if ( topRow > bottomRow )
     {
         int temp = topRow;
         topRow = bottomRow;
         bottomRow = temp;
     }

     if ( leftCol > rightCol )
     {
         int temp = leftCol;
         leftCol = rightCol;
         rightCol = temp;
     }

     // Handle single cell selection in SelectCell.
     // (MB: added check for selection mode here to prevent
     //  crashes if, for example, we are select rows and the
     //  grid only has 1 col)
     if ( m_selectionMode == wxGrid::wxGridSelectCells &&
          topRow == bottomRow && leftCol == rightCol )
         SelectCell( topRow, leftCol, ControlDown,  ShiftDown,
                     AltDown, MetaDown, sendEvent );

     size_t count, n;
     // Remove single cells contained in newly selected block.
     if ( m_selectionMode == wxGrid::wxGridSelectCells )
     {
         count = m_cellSelection.GetCount();
         for ( n = 0; n < count; n++ )
         {
             wxGridCellCoords& coords = m_cellSelection[n];
             if ( BlockContainsCell( topRow, leftCol, bottomRow, rightCol,
                                     coords.GetRow(), coords.GetCol() ) )
             {
                 m_cellSelection.RemoveAt(n);
                 n--; count--;
             }
         }
     }

     // If a block containing the selection is already selected, return,
     // if a block contained in the selection is found, remove it.

     count = m_blockSelectionTopLeft.GetCount();
     for ( n = 0; n < count; n++ )
     {
         wxGridCellCoords& coords1 = m_blockSelectionTopLeft[n];
         wxGridCellCoords& coords2 = m_blockSelectionBottomRight[n];
         switch ( BlockContain( coords1.GetRow(), coords1.GetCol(),
                                coords2.GetRow(), coords2.GetCol(),
                                topRow, leftCol, bottomRow, rightCol ) )
         {
           case 1:
             return;
           case -1:
             m_blockSelectionTopLeft.RemoveAt(n);
             m_blockSelectionBottomRight.RemoveAt(n);
             n--; count--;
           default:
             ;
         }
     }

     // If a row containing the selection is already selected, return,
     // if a row contained in newly selected block is found, remove it.
     if ( m_selectionMode != wxGrid::wxGridSelectColumns )
     {
         count = m_rowSelection.GetCount();
         for ( n = 0; n < count; n++ )
         {
             switch ( BlockContain( m_rowSelection[n], 0,
                                    m_rowSelection[n],

                                    topRow, leftCol, bottomRow,

             {
               case 1:
                 return;
               case -1:
                 m_rowSelection.RemoveAt(n);
                 n--; count--;
               default:
                 ;
             }
         }
     }
     if ( m_selectionMode != wxGrid::wxGridSelectRows )
     {
         count = m_colSelection.GetCount();
         for ( n = 0; n < count; n++ )
         {
             switch ( BlockContain( 0, m_colSelection[n],
                                    m_grid->GetNumberRows()-1,

                                    topRow, leftCol, bottomRow,

             {
               case 1:
                 return;
               case -1:
                 m_colSelection.RemoveAt(n);
                 n--; count--;
               default:
                 ;
             }
         }
     }
     m_blockSelectionTopLeft.Add( wxGridCellCoords( topRow, leftCol ) );
     m_blockSelectionBottomRight.Add( wxGridCellCoords( bottomRow,

     // Update View:
     wxRect r = m_grid->BlockToDeviceRect( wxGridCellCoords( topRow,

                                           wxGridCellCoords( bottomRow,

     if ( !m_grid->GetBatchCount() )
         ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r );

     // Send Event, if not disabled.
     if ( sendEvent )
     {
         wxGridRangeSelectEvent gridEvt( m_grid->GetId(),
                                         wxEVT_GRID_RANGE_SELECT,
                                         m_grid,
                                         wxGridCellCoords( topRow,

                                         wxGridCellCoords( bottomRow,

                                         TRUE,
                                         ControlDown, ShiftDown,
                                         AltDown, MetaDown );
         m_grid->GetEventHandler()->ProcessEvent(gridEvt);
     }
 }

 void wxGridSelection::SelectCell( int row, int col,
                                   bool ControlDown, bool ShiftDown,
                                   bool AltDown, bool MetaDown,
                                   bool sendEvent )
 {
     if ( m_selectionMode == wxGrid::wxGridSelectRows )
     {
         SelectBlock(row, 0, row, m_grid->GetNumberCols() - 1,
                     ControlDown, ShiftDown, AltDown, MetaDown, sendEvent);
         return;
     }
     else if ( m_selectionMode == wxGrid::wxGridSelectColumns )
     {
         SelectBlock(0, col, m_grid->GetNumberRows() - 1, col,
                     ControlDown, ShiftDown, AltDown, MetaDown, sendEvent);
         return;
     }
     else if ( IsInSelection ( row, col ) )
         return;
     m_cellSelection.Add( wxGridCellCoords( row, col ) );

     // Update View:
     wxRect r = m_grid->BlockToDeviceRect( wxGridCellCoords( row, col ),
                                           wxGridCellCoords( row, col ) );
     if ( !m_grid->GetBatchCount() )
         ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r );

     // Send event
     if (sendEvent)
     {
         wxGridRangeSelectEvent gridEvt( m_grid->GetId(),
                                         wxEVT_GRID_RANGE_SELECT,
                                         m_grid,
                                         wxGridCellCoords( row, col ),
                                         wxGridCellCoords( row, col ),
                                         TRUE,
                                         ControlDown, ShiftDown,
                                         AltDown, MetaDown);
         m_grid->GetEventHandler()->ProcessEvent(gridEvt);
     }
 }

 void wxGridSelection::ToggleCellSelection( int row, int col,
                                            bool ControlDown, bool

                                            bool AltDown, bool MetaDown )
 {
     // if the cell is not selected, select it
     if ( !IsInSelection ( row, col ) )
     {
         SelectCell( row, col, ControlDown, ShiftDown,
                     AltDown, MetaDown );
         return;
     }

     // otherwise deselect it. This can be simple or more or
     // less difficult, depending on how the cell is selected.
     size_t count, n;

     // The simplest case: The cell is contained in m_cellSelection
     // Then it can't be contained in rows/cols/block (since those
     // would remove the cell from m_cellSelection on creation), so
     // we just have to remove it from m_cellSelection.

     if ( m_selectionMode == wxGrid::wxGridSelectCells )
     {
         count = m_cellSelection.GetCount();
         for ( n = 0; n < count; n++ )
         {
             wxGridCellCoords& coords = m_cellSelection[n];
             if ( row == coords.GetRow() && col == coords.GetCol() )
             {
                 wxRect r;
                 r = m_grid->BlockToDeviceRect( m_cellSelection[n],
                                                m_cellSelection[n] );
                 m_cellSelection.RemoveAt(n);
                 n--; count--;
                 if ( !m_grid->GetBatchCount() )
                     ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r );

                 // Send event
                 wxGridRangeSelectEvent gridEvt( m_grid->GetId(),
                                                 wxEVT_GRID_RANGE_SELECT,
                                                 m_grid,
                                                 wxGridCellCoords( row,

                                                 wxGridCellCoords( row,

                                                 FALSE,
                                                 ControlDown, ShiftDown,
                                                 AltDown, MetaDown );
                 m_grid->GetEventHandler()->ProcessEvent(gridEvt);
                 return;
             }
         }
     }

     // The most difficult case: The cell is member of one or even several
     // blocks. Split each such block in up to 4 new parts, that don't
     // contain the cell to be selected, like this:
     // |---------------------------|
     // |                           |
     // |           part 1          |
     // |                           |
     // |---------------------------|
     // |   part 3   |x|   part 4   |
     // |---------------------------|
     // |                           |
     // |           part 2          |
     // |                           |
     // |---------------------------|
     //   (The x marks the newly deselected cell).
     // Note: in row selection mode, we only need part1 and part2;
     //       in column selection mode, we only need part 3 and part4,
     //          which are expanded to whole columns automatically!

     count = m_blockSelectionTopLeft.GetCount();
     for ( n = 0; n < count; n++ )
       {
         wxGridCellCoords& coords1 = m_blockSelectionTopLeft[n];
         wxGridCellCoords& coords2 = m_blockSelectionBottomRight[n];
         int topRow = coords1.GetRow();
         int leftCol = coords1.GetCol();
         int bottomRow = coords2.GetRow();
         int rightCol = coords2.GetCol();
         if ( BlockContainsCell( topRow, leftCol, bottomRow, rightCol,
                                 row, col ) )
         {
             // remove the block
             m_blockSelectionTopLeft.RemoveAt(n);
             m_blockSelectionBottomRight.RemoveAt(n);
             n--; count--;
             // add up to 4 smaller blocks and set update region
             if ( m_selectionMode != wxGrid::wxGridSelectColumns )
             {
                 if ( topRow < row )
                     SelectBlock( topRow, leftCol, row - 1, rightCol,
 FALSE, FALSE, FALSE, FALSE, FALSE );
                 if ( bottomRow > row )
                     SelectBlock( row + 1, leftCol, bottomRow, rightCol,
 FALSE, FALSE, FALSE, FALSE, FALSE );
             }
             if ( m_selectionMode != wxGrid::wxGridSelectRows )
             {
                 if ( leftCol < col )
                     SelectBlock( row, leftCol, row, col - 1,
 FALSE, FALSE, FALSE, FALSE, FALSE );
                 if ( rightCol > col )
                     SelectBlock( row, col + 1, row, rightCol,
 FALSE, FALSE, FALSE, FALSE, FALSE );
             }
         }
     }

     // remove a cell from a row, adding up to two new blocks
     if ( m_selectionMode != wxGrid::wxGridSelectColumns )
     {
         count = m_rowSelection.GetCount();
         for ( n = 0; n < count; n++ )
         {
             if ( m_rowSelection[n] == row )
             {
                 m_rowSelection.RemoveAt(n);
                 n--; count--;
                 if (m_selectionMode == wxGrid::wxGridSelectCells)
                 {
                     if ( col > 0 )
                         SelectBlock( row, 0, row, col - 1,
      FALSE, FALSE, FALSE, FALSE, FALSE );
                     if ( col < m_grid->GetNumberCols() - 1 )
                         SelectBlock( row, col + 1,
                                      row, m_grid->GetNumberCols() - 1,
                                      FALSE, FALSE, FALSE, FALSE, FALSE );
                 }
             }
         }
     }

     // remove a cell from a column, adding up to two new blocks
     if ( m_selectionMode != wxGrid::wxGridSelectRows )
     {
         count = m_colSelection.GetCount();
         for ( n = 0; n < count; n++ )
         {
             if ( m_colSelection[n] == col )
             {
                 m_colSelection.RemoveAt(n);
                 n--; count--;
                 if (m_selectionMode == wxGrid::wxGridSelectCells)
                 {
                     if ( row > 0 )
                         SelectBlock( 0, col, row - 1, col,
      FALSE, FALSE, FALSE, FALSE, FALSE );
                     if ( row < m_grid->GetNumberRows() - 1 )
                         SelectBlock( row + 1, col,
                                      m_grid->GetNumberRows() - 1, col,
                                      FALSE, FALSE, FALSE, FALSE, FALSE );
                 }
             }
         }
     }

     // Refresh the screen and send the event; according to

     // we need to either update only the cell, or the whole row/column.
     wxRect r;
     switch (m_selectionMode)
     {
       case wxGrid::wxGridSelectCells:
       {
           r = m_grid->BlockToDeviceRect( wxGridCellCoords( row, col ),
                                          wxGridCellCoords( row, col ) );
           if ( !m_grid->GetBatchCount() )
               ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r );
           wxGridRangeSelectEvent gridEvt( m_grid->GetId(),
                                           wxEVT_GRID_RANGE_SELECT,
                                           m_grid,
                                           wxGridCellCoords( row, col ),
                                           wxGridCellCoords( row, col ),
                                           FALSE,
                                           ControlDown, ShiftDown,
                                           AltDown, MetaDown );
           m_grid->GetEventHandler()->ProcessEvent(gridEvt);
           break;
       }
       case wxGrid::wxGridSelectRows:
       {
           r = m_grid->BlockToDeviceRect( wxGridCellCoords( row, 0 ),
                                          wxGridCellCoords( row,

           if ( !m_grid->GetBatchCount() )
               ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r );
           wxGridRangeSelectEvent gridEvt( m_grid->GetId(),
                                           wxEVT_GRID_RANGE_SELECT,
                                           m_grid,
                                           wxGridCellCoords( row, 0 ),
                                           wxGridCellCoords( row,

                                           FALSE,
                                           ControlDown, ShiftDown,
                                           AltDown, MetaDown );
           m_grid->GetEventHandler()->ProcessEvent(gridEvt);
           break;
       }
       case wxGrid::wxGridSelectColumns:
       {
           r = m_grid->BlockToDeviceRect( wxGridCellCoords( 0, col ),
                                          wxGridCellCoords(

           if ( !m_grid->GetBatchCount() )
               ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r );
           wxGridRangeSelectEvent gridEvt( m_grid->GetId(),
                                           wxEVT_GRID_RANGE_SELECT,
                                           m_grid,
                                           wxGridCellCoords( 0, col ),
                                           wxGridCellCoords(

                                           FALSE,
                                           ControlDown, ShiftDown,
                                           AltDown, MetaDown );
           m_grid->GetEventHandler()->ProcessEvent(gridEvt);
           break;
       }
     }
 }

 void wxGridSelection::ClearSelection()
 {
     size_t n;

     // deselect all invidiual cells and update the screen
     if ( m_selectionMode == wxGrid::wxGridSelectCells )
     {

         while( ( n = m_cellSelection.GetCount() ) > 0)
         {
             wxRect r;
             n--;
             r = m_grid->BlockToDeviceRect( m_cellSelection[n],
                                            m_cellSelection[n] );
             m_cellSelection.RemoveAt(n);
             if ( !m_grid->GetBatchCount() )
                 ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r );
         }
     }

     // deselect all blocks and update the screen
     while( ( n = m_blockSelectionTopLeft.GetCount() ) > 0)
     {
         wxRect r;
         n--;
         r = m_grid->BlockToDeviceRect( m_blockSelectionTopLeft[n],
                                        m_blockSelectionBottomRight[n] );
         m_blockSelectionTopLeft.RemoveAt(n);
         m_blockSelectionBottomRight.RemoveAt(n);
         if ( !m_grid->GetBatchCount() )
             ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r );
     }

     // deselect all rows and update the screen
     if ( m_selectionMode != wxGrid::wxGridSelectColumns )
     {
         while( ( n = m_rowSelection.GetCount() ) > 0)
         {
             n--;
             int & row = m_rowSelection[n];
             wxRect r;
             r = m_grid->BlockToDeviceRect( wxGridCellCoords( row, 0 ),
                                            wxGridCellCoords( row,

             m_rowSelection.RemoveAt(n);
             if ( !m_grid->GetBatchCount() )
                 ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r );
         }
     }

     // deselect all columns and update the screen
     if ( m_selectionMode != wxGrid::wxGridSelectRows )
     {
         while( ( n = m_colSelection.GetCount() ) > 0)
         {
             n--;
             int & col = m_colSelection[n];
             wxRect r;
             r = m_grid->BlockToDeviceRect( wxGridCellCoords( 0, col ),
                                            wxGridCellCoords(

             m_colSelection.RemoveAt(n);
             if ( !m_grid->GetBatchCount() )
                 ((wxWindow *)m_grid->m_gridWin)->Refresh( FALSE, &r );
         }
     }

     // One deselection event, indicating deselection of _all_ cells.
     // (No finer grained events for each of the smaller regions
     //  deselected above!)
     wxGridRangeSelectEvent gridEvt( m_grid->GetId(),
                                     wxEVT_GRID_RANGE_SELECT,
                                     m_grid,
                                     wxGridCellCoords( 0, 0 ),
                                     wxGridCellCoords(


                                     FALSE );

     m_grid->GetEventHandler()->ProcessEvent(gridEvt);
 }


 void wxGridSelection::UpdateRows( size_t pos, int numRows )
 {
     size_t count = m_cellSelection.GetCount();
     size_t n;
     for ( n = 0; n < count; n++ )
     {
         wxGridCellCoords& coords = m_cellSelection[n];
         wxCoord row = coords.GetRow();
         if ((size_t)row >= pos)
         {
             if (numRows > 0)
             {
                 // If rows inserted, increase row counter where necessary
                 coords.SetRow(row + numRows);
             }
             else if (numRows < 0)
             {
                 // If rows deleted ...
                 if ((size_t)row >= pos - numRows)
                 {
                     // ...either decrement row counter (if row still

                     coords.SetRow(row + numRows);
                 }
                 else
                 {
                     // ...or remove the attribute
                     m_cellSelection.RemoveAt(n);
                     n--; count--;
                 }
             }
         }
     }

     count = m_blockSelectionTopLeft.GetCount();
     for ( n = 0; n < count; n++ )
     {
         wxGridCellCoords& coords1 = m_blockSelectionTopLeft[n];
         wxGridCellCoords& coords2 = m_blockSelectionBottomRight[n];
         wxCoord row1 = coords1.GetRow();
         wxCoord row2 = coords2.GetRow();
         if ((size_t)row2 >= pos)
         {
             if (numRows > 0)
             {
                 // If rows inserted, increase row counter where necessary
                 coords2.SetRow(row2 + numRows);
                 if ( (size_t)row1 >= pos )
                     coords1.SetRow(row1 + numRows);
             }
             else if (numRows < 0)
             {
                 // If rows deleted ...
                 if ((size_t)row2 >= pos - numRows)
                 {
                     // ...either decrement row counter (if row still

                     coords2.SetRow(row2 + numRows);
                     if ( (size_t) row1 >= pos)
                         coords1.SetRow( wxMax(row1 + numRows, (int)

                 }
                 else
                 {
                     if ( (size_t) row1 >= pos)
                     {
                         // ...or remove the attribute
                         m_blockSelectionTopLeft.RemoveAt(n);
                         m_blockSelectionBottomRight.RemoveAt(n);
                         n--; count--;
                     }
                     else
                         coords2.SetRow(pos);
                 }
             }
         }
     }

     count = m_rowSelection.GetCount();
     for ( n = 0; n < count; n++ )
     {
 #if ( __DMC__ < 0x835 )
         int & rowOrCol = m_rowSelection[n];
         if ( (size_t)rowOrCol >= pos )
         {
             if ( numRows > 0 )
             {
                 // If rows inserted, include row counter where necessary
                 rowOrCol += numRows;
             }
             else if ( numRows < 0)
             {
                 // If rows deleted, either decrement row counter (if row

                 if ((size_t)rowOrCol >= pos - numRows)
                     rowOrCol += numRows;
                 else
                 {
                     m_rowSelection.RemoveAt(n);
                     n--; count--;
                 }
             }
         }
 #else
 #pragma message ( "DMC: alternate implementation due to problems with DMC

       int  rowOrCol_ = m_rowSelection [ n ];

       if ( ( size_t ) rowOrCol_ >= pos )
       {
           if ( numRows > 0 )
           {
               m_rowSelection [ n ] += numRows;
           }
           else if ( numRows < 0 )
           {
               if ( ( size_t ) rowOrCol_ >= ( pos - numRows ) )
                   m_rowSelection [ n ] += numRows;
               else
               {
                   m_rowSelection.RemoveAt ( n );
                   n--;
                   count--;
               }
           }
       }
 #endif
     }
     // No need to touch selected columns, unless we removed _all_
     // rows, in this case, we remove all columns from the selection.

     if ( !m_grid->GetNumberRows() )
         m_colSelection.Clear();
 }


 void wxGridSelection::UpdateCols( size_t pos, int numCols )
 {
     size_t count = m_cellSelection.GetCount();
     size_t n;
     for ( n = 0; n < count; n++ )
     {
         wxGridCellCoords& coords = m_cellSelection[n];
         wxCoord col = coords.GetCol();
         if ((size_t)col >= pos)
         {
             if (numCols > 0)
             {
                 // If rows inserted, increase row counter where necessary
                 coords.SetCol(col + numCols);
             }
             else if (numCols < 0)
             {
                 // If rows deleted ...
                 if ((size_t)col >= pos - numCols)
                 {
                     // ...either decrement row counter (if row still

                     coords.SetCol(col + numCols);
                 }
                 else
                 {
                     // ...or remove the attribute
                     m_cellSelection.RemoveAt(n);
                     n--; count--;
                 }
             }
         }
     }

     count = m_blockSelectionTopLeft.GetCount();
     for ( n = 0; n < count; n++ )
     {
         wxGridCellCoords& coords1 = m_blockSelectionTopLeft[n];
         wxGridCellCoords& coords2 = m_blockSelectionBottomRight[n];
         wxCoord col1 = coords1.GetCol();
         wxCoord col2 = coords2.GetCol();
         if ((size_t)col2 >= pos)
         {
             if (numCols > 0)
             {
                 // If rows inserted, increase row counter where necessary
                 coords2.SetCol(col2 + numCols);
                 if ( (size_t)col1 >= pos )
                     coords1.SetCol(col1 + numCols);
             }
             else if (numCols < 0)
             {
                 // If cols deleted ...
                 if ((size_t)col2 >= pos - numCols)
                 {
                     // ...either decrement col counter (if col still

                     coords2.SetCol(col2 + numCols);
                     if ( (size_t) col1 >= pos)
                         coords1.SetCol( wxMax(col1 + numCols, (int)

                 }
                 else
                 {
                     if ( (size_t) col1 >= pos)
                     {
                         // ...or remove the attribute
                         m_blockSelectionTopLeft.RemoveAt(n);
                         m_blockSelectionBottomRight.RemoveAt(n);
                         n--; count--;
                     }
                     else
                         coords2.SetCol(pos);
                 }
             }
         }
     }

     count = m_colSelection.GetCount();
     for ( n = 0; n < count; n++ )
     {
 #if ( __DMC__ < 0x835 )
         int & rowOrCol = m_colSelection[n];
         if ( (size_t)rowOrCol >= pos )
         {
             if ( numCols > 0 )
             {
                 // If cols inserted, include col counter where necessary
                 rowOrCol += numCols;
             }
             else if ( numCols < 0)
             {
                 // If cols deleted, either decrement col counter (if col

                 if ((size_t)rowOrCol >= pos - numCols)
                     rowOrCol += numCols;
                 else
                 {
                     m_colSelection.RemoveAt(n);
                     n--; count--;
                 }
             }
         }
 #else
 #pragma message ( "DMC: alternate implementation due to problems with DMC

         int   rowOrCol = m_colSelection [ n ];
         if ( ( size_t ) rowOrCol >= pos )
         {
             if ( numCols > 0 )
                 m_colSelection [ n ] += numCols;
             else if ( numCols < 0 )
             {
                 if ( ( size_t ) rowOrCol >= ( pos -numCols ) )
                     m_colSelection [ n ] += numCols;
                 else
                 {
                     m_colSelection.RemoveAt ( n );
                     n--;
                     count--;
                 }
             }
         }
 #endif
     }

     // No need to touch selected rows, unless we removed _all_
     // columns, in this case, we remove all rows from the selection.
     if ( !m_grid->GetNumberCols() )
         m_rowSelection.Clear();
 }


 int wxGridSelection::BlockContain( int topRow1, int leftCol1,
                                    int bottomRow1, int rightCol1,
                                    int topRow2, int leftCol2,
                                    int bottomRow2, int rightCol2 )
 // returns 1, if Block1 contains Block2,
 //        -1, if Block2 contains Block1,
 //         0, otherwise
 {
     if ( topRow1 <= topRow2 && bottomRow2 <= bottomRow1 &&
          leftCol1 <= leftCol2 && rightCol2 <= rightCol1 )
         return 1;
     else if ( topRow2 <= topRow1 && bottomRow1 <= bottomRow2 &&
               leftCol2 <= leftCol1 && rightCol1 <= rightCol2 )
         return -1;
     return 0;
 }

 #endif

Aug 26 2003
prev sibling next sibling parent reply Sergey Gutnikov <Sergey_member pathlink.com> writes:
In article <bi8tir$loe$1 digitaldaemon.com>, Walter says...
An accummulation of a lot of minor fixes. Now has STLSoft 1.6.5.

http://www.digitalmars.com/compiler.htm

Dear Walter, Following bugs have been found in Digital Mars C++ CD version 8.35 ***1) Problem: 8.35 compiler does not generate code for static destructors. Here is a short example (files buf.h, buf.cpp, test.cpp): //--- buf.h: #include <stdio.h> #include <stdlib.h> extern "C++" char * get_buffer( size_t size ); //--- buf.h <eof> //--- buf.cpp: #include "buf.h" static char * pbuf = NULL; static size_t nsize = 0; class bufTerminate { public: ~bufTerminate() { printf( "bufTerminate::~bufTerminate() called\n" ); if ( pbuf != NULL ) { free( pbuf ); } } }; static bufTerminate terminator; char * get_buffer( size_t size ) { printf( "get_buffer(%d) called\n", size ); if ( size > nsize ) { char * buf = (char *) realloc( pbuf, size ); if ( buf == NULL ) { printf( "Unable to allocate memory block\n" ); return NULL; } nsize = size; pbuf = buf; } return pbuf; } //--- buf.cpp <eof> //--- test.cpp #include "buf.h" void main() { char * p; p = get_buffer( 4096 ); // ... p = get_buffer( 4096 * 2 ); // ... p = get_buffer( 4096 * 4 ); // ... } //--- test.cpp <eof> Files have been compiled in versions 8.34 and 8.35 by the following command: E:\bug>sc -mn -5 -Nc -o+all -o+time -D_CONSOLE test.cpp buf.cpp test.cpp: buf.cpp: link test+buf,,,user32+kernel32/noi; Program output (version 8.34): E:\bug>test.exe get_buffer(4096) called get_buffer(8192) called get_buffer(16384) called bufTerminate::~bufTerminate() called Program output (version 8.35): E:\bug>test.exe get_buffer(4096) called get_buffer(8192) called get_buffer(16384) called ***2) Problem: _vstprintf macro (tchar.h): _vstprintf has different number of arguments depend on _UNICODE macro defined or not. _UNICODE undefined: _vstprintf(buffer,format,argptr) _UNICODE=1: _vstprintf(buffer,size,format,argptr) Regards... Sergey Gutnikov
Aug 30 2003
next sibling parent "Walter" <walter digitalmars.com> writes:
What's happening is that since 'terminator' is never referenced, it is never
allocated. That's probably a compiler bug. To work around, create a
reference to it.
Aug 30 2003
prev sibling parent "Walter" <walter digitalmars.com> writes:
Try the new beta 8.36.1.
Aug 31 2003
prev sibling parent Craig Bowlas <craig NObowlasSPAM.demon.co.uk> writes:
Hi,

I have upgraded my Digital Mars CD version to this version and when I
attempt to compile an MFC app form the IDDE using the Debug options I
get a string of "Bad Type Index reference to type 2093" against the
snnd.lib library.  When I check the dates on the libs I find that the
debug lib snnd.lib is older that the release counterpart snn.lib.
This library seems to be the one incorporated in the 8.3.5 update zip.
Is it out of date?  


Regards

Craig

PS.  Love the tool chain.  I have been a user since the zorLAND days!


On Sat, 23 Aug 2003 16:27:07 -0700, "Walter" <walter digitalmars.com>
wrote:

An accummulation of a lot of minor fixes. Now has STLSoft 1.6.5.

http://www.digitalmars.com/compiler.htm

Aug 31 2003