We value your input! Please participate in Archicad 28 Home Screen and Tooltips/Quick Tutorials survey
2004-07-01 03:49 PM - last edited on 2023-08-07 12:18 PM by Doreena Deng
#include "DG.h" // brings file selection dialog (and also includes Location) IO::Location loc; if (!DGGetOpenFile (&loc)) { // returns the selected location in loc // no file (folder, link) location was selected }but I just couldn't get it to work. I even searched through all the documentation without finding any other reference to DGGetOpenFile. So I gave it up.
IO::Location fileLoc; // Location instance IO::File file (fileLoc); char buffer[128]; DG::FileDialog dlg (DG::FileDialog::OpenMultiFile); if (!dlg.Invoke ()) return false; int count = dlg.GetSelectionCount (); for (int n = 0; n < count; n++) { IO::File file (dlg.GetSelectedFile (n)); errorCode = file.Open (IO::File::ReadMode); // opening the file in read-only mode errorCode = file.ReadBin(buffer, 128); DGAlert(DG_INFORMATION, "Inside while", buffer, 0, "OK", "Cancel", 0); }This lets me open my file from a filedialog. One problem though, is that I can't open it as myFile.sos, which is what it is, I have to rename it to myFile.txt. Why is that, and what can I do with it?
2004-07-01 03:58 PM
FILE *stream; if( (stream = fopen("test.dat", "w"))!=NULL) { fprintf( stream, "blablah %.3f \n", 27.0); } fclose(stream); _fcloseall(); _flushall();I guess, for ArchiCAD conformance, you should try to use the API-tools instead. Don't know how portable this is and you probably want to use the sytem FileOpen & Save-dialogs as well...
2004-07-01 10:21 PM
Tor wrote:I haven't found any reference to this either, but it does work with a slight modification. Without specific documentation, you can often find the information you need by searching through the Support files, especially the Include files. For example, the declaration of DGGetOpenFile is:IO::Location loc; if (!DGGetOpenFile (&loc)) { // returns the selected location in loc // no file (folder, link) location was selected }but I just couldn't get it to work. I even searched through all the documentation without finding any other reference to DGGetOpenFile.
DG_DLL_EXPORT bool CCALL DGGetOpenFile (CIO::Location* retLocation, long popupItemCount = 0, DGTypePopupItem* popupItems = NULL, const CIO::Location* defLocation = NULL, const char* title = NULL, long flags = 0); DG_DLL_EXPORT long CCALL DGGetOpenFile (CIO::Location** retLocationArray, long popupItemCount = 0, DGTypePopupItem* popupItems = NULL, const CIO::Location* defLocation = NULL, const char* title = NULL, long flags = 0);This shows us there are two variants of this function: one which allows a single file to be selected, and another for multiple files. You probably want the first. This expects a pointer to a CIO::Location (try this instead of IO::Location).
struct DGTypePopupItem { const char* text; const char* extensions; long macType; };Briefly, you specify a name for the filter, the name extension, and a Macintosh file type descriptor (4 chars).
// --- Constants for DGGetOpenFile --------------------------------------------- #define DG_OF_NO_ALL_FILES 0x0001 #define DG_OF_NO_ROOT_GROUP 0x0002 #define DG_OF_GROUPS_FIRST 0x0004 #define DG_OF_DISPLAY_EXTENSIONS 0x0008 #define DG_OF_DONT_DISPLAY_EXTENSIONS 0x0010 #define DG_OF_LIST_SINGLE_CHILD_GROUPS 0x0020So, if you wanted the user to open a single plain text file, and you didn't want to see all file types, you could write:
CIO::Location loc; DGTypePopupItem popup[1] = { {"Plain Text", "txt", 'TEXT'} }; if (!DGGetOpenFile (&loc, 1, popup, 0, "Test", DG_OF_NO_ALL_FILES)) { //No file selected }
Tor wrote:You can use standard the C/C++ library (or others) for strings and i/o, but there are some issues to consider. Are you sure the file content is always text? And, more importantly, what is the encoding of the text, e.g. UTF8? You need to keep in mind that a single character is not necessarily a single byte.
The other thing is that I can't read one line at the time. How do I do that? ... if I can't read one line at the time, how do I read the whole file at once. And then the stringmanager doesn't seem too equiped whith functions to parse the text and split it up in sutable chunks. Can I use standard c++ functions and includes as well as the ones that comes with the API?
2004-07-02 12:46 PM
When you say you want to read a line, do you mean a line terminated by some combination of carriage return and linefeed, or a logical line in the syntax of the file format you are parsing? In any case, you need to parse the text - accumulating everything you read to a buffer - until you discover the conditions which terminate the line (or the file).I mean a line terminated by some combination of carriage return and linefeed.
You could then allocate a memory block large enough to accomodate the entire file and read it in one hit. You need to consider what size these files may be if you take this approach - buffering the contents will likely be far more efficient.
errorCode = file.GetDataLength(&fLength);but I'm not allowed to use the fLength-value to set the length of my charbuffer.
2004-07-02 02:17 PM
Tor wrote:OK. Standard line endings are:
Ralph wrote:When you say you want to read a line, do you mean... etcI mean a line terminated by some combination of carriage return and linefeed.
Tor wrote:As I mentioned above, your text may well be encoded. Basically, the old ASCII codes allowed for only 256 character symbols at most (1 byte per character), but many languages have vastly more symbols than that. Therefore, text needs to be in a form which can account for thousands of character symbols and also provide for commonality between them, e.g. common numeric symbols. This is a fairly deep subject, but the String Manager functions in the ArchiCAD API may be able to provide what you need.
When I start reading the first part of the first line, which goes like this:
.HODE 0:
and writes it to the alert or the reportwindow, what I get is this:
.??†
etc...
Tor wrote:I don't know what you mean by, "not allowed to use fLength" - it's just a number which can be used to allocate a block of memory. Are you doing something like this:You could then allocate a memory block large enough to accomodate the entire file...
I've tried to useerrorCode = file.GetDataLength(&fLength);but I'm not allowed to use the fLength-value to set the length of my charbuffer.
USize fLength = 0; file.GetDataLength(&fLength); GSPtr buff = BMAllocatePtr(fLength, ALLOCATE_CLEAR, 0);You can then read the file data into 'buff'.
Tor wrote:Did you copy/paste my example into your file?
And I still can't make the DGGetOpenFile() work. I've included DG.h, File.hpp and Filesystem.hpp, do I need more?
CIO::Location loc; DGTypePopupItem popup[1] = { {"Plain Text", "txt", 'TEXT'} }; if (!DGGetOpenFile (&loc, 1, popup, 0, "Test", DG_OF_NO_ALL_FILES)) { //No file selected }Does this work?
2004-07-03 07:35 PM
2004-07-04 04:21 PM
2004-07-05 10:22 AM
GSPtr buff = BMAllocatePtr(fLength, ALLOCATE_CLEAR, 0); errorCode = file.ReadBin(buff, fLength);
GSPtr linePtr = CHSearchSubstring("\r", buff, fLength); // pointing to the first cr
2004-07-05 11:10 AM
2004-07-05 12:18 PM