Frederick2 189 Posting Whiz

I'm doing command line compiling, and thought there might be some switch that would list starting and finishing time, but couldn't find anything. I'm using Windows, and trying to work with the default gcc/g++ from mingw installed with Code::Blocks. Or is there some way of doing this with some shell command? There's got to be a way?

Frederick2 189 Posting Whiz

In your CreateWindow() calls for the edit controls, you are not passing the correct HINSTANCE of the app.

Frederick2 189 Posting Whiz

Thanks MosaicFuneral and Narue.

Say, MolsaicFuneral! I've got it about half working modifying my String Class to save the string length in a member variable, instead of constantly calling strlen(), and it looks like something like a 90 to 95% improvement in speed! Can't believe I didn't think of that myhself, its so basic. I've more work to do with it yet though.

Frederick2 189 Posting Whiz

What is the difference between size_t and size_type? size_type seems to be related closely with the C++ Standard String Class. Couldn't they have just used size_t instead? I don't understand the difference. Could anyone elaborate please?

Frederick2 189 Posting Whiz

I finally got your point MosaicFuneral. I haven't been saving the string length of 'this' in any of my member functions. That I haven't no doubt goes all the way back to when I first started to develop my own string class 3 or 4 years ago, I was only concerned with getting it to work at all; I wasn't concerned with speed or efficiency. Until now, that is. The way it is now my string lengths are being calculated in every member function call, and each concatenation in a loop is making about four calls or so. So I've added a private string length member to my class, and I'm working through the code now making the necessary changes. All the while I'm thinking, "Wow! "Should have done this before!". When I get it done I come back with the performance improvements. I can't help thinking they'll be substantial.

Frederick2 189 Posting Whiz

The original poster has returned!

Thanks for the additional feedback rich1231 and jlego! Makes me glad its not just me interested in such retrogressive things!

I've never played around with the virtual machine stuff yet. I frequently however set up my machines as dual boot with Linux and Windows. Seems like I never really get a chance to work with Linux much. I work in pretty much a Windows world.

The basis for my question though is as follows. A number of years ago I screwed up the MBR of one of my good laptops, and all I could figure out to fix it was to FDisk it with some DOS 6.2 OS disks I had. Out of curiousity I put Win 98 back on it after getting it straightened out instead of the Win 2000 it came with. It was a pretty top end Win 2000 machine with an at the time fast processor. Well, what a surprise I got!!! Instead of the usual 2 or 3 minutes one usually waits for a machine to boot up, the darn thing came on almost like turning on a light switch! At that point it really dawned on me the extent to which code bloat is out pacing hardware development.

I'm basically a low level coder and tend to not create bloated solutions for the work I do. And I also don't need the latest and greatest bleeding edge type stuff. Old hardware suits me fine. Like …

Frederick2 189 Posting Whiz

That did it Vijayan! You are a master! That code beats everything I've tried so far! I won't be pestering you again. I guess I need to learn STL.

Frederick2 189 Posting Whiz

Thanks for looking at my posts MosaicFuneral. That link you gave is interesting. I’m going to save and study it. In terms of this…

Store the string length before hand, add the length of the two strings to find the new length, if
the new length is greater than the current capacity then you call to increase the size, then call
to have the the data of the new string concatenated to yours.

I do believe I’m already doing that. Here are the private data members of my String Class…

private:
 TCHAR* pStrBuffer;                   //Holds String Buffer Allocated In Various Overloaded Constructors And Members
 int    iAllowableCharacterCount;     //Persists Number of characters which will fit in this->pStrBuffer

All my member functions which allocate memory (constructors, overloaded operator functions, etc.) allocate it on 16 byte paragraph boundaries and always round up to multiples of 16 bytes. Here is my operator+= member. You can see the very first line obtains the length of the string controlled by ‘this’ plus the length to be added, i.e., strRight. If the buffer indicated by my iAllowableCharacterCount member is big enough, the strRight is strcat()’ed to it. If not, a memory re-allocation occurs, and both strings are moved to the new and larger buffer. I might point out that in the real program there would be next to none of this time wasting re-allocation and string movement taking place. My swap/temp space is s2. Here it would have been made large enough to accommodate the …

Frederick2 189 Posting Whiz

Here is the link to the other thread referred to in this post where all my String Class code for the full class is located, along with a number of programs utilizing it and their relative performance...

http://www.daniweb.com/forums/thread340738.html

Frederick2 189 Posting Whiz

I typically debug that way. I don't always like conditional compilation code in my programs. I do do that about half the time though. In this case I thought console output would be fine, as its just a small test program.

Frederick2 189 Posting Whiz

Hello Vivayan!

Its taken me this long to understand your sophisticated program you gave me using STL (Standard Template Library) iterators, container classes, algorithms, and the works! I’m truly grateful for the time you took to develop this program for me, and it inspired me so much I’ve decided to finally tackle learning some STL and such. I can see you are a master at this! I just bought Bruce Eckel’s “Thinking In C++”, Volume 2, because in it he covers String Classes, STL, templates, and so forth. Anyway, to refresh your memory, here are the original requirements again…

'1) Create a 2000000 character string of dashes or spaces;
'2) Change every 7th dash or space to a "P";
'3) Replace every "P" with a "PU" (hehehe);
'4) Replace every dash or space with an "8";
'5) Put in a carriage return & line feed every 90 characters;
'6) Output last 4000 characters.

…and here is the program you developed for me (I made a few minor changes, i.e., GetTickCount(), printf instead of iostream)…

#include "Windows.h"
#include "stdio.h"
#include <string>
#include <algorithm>

int main()
{
 enum { K = 7, N = 2*1024*1024, N1 = N + N/7, BLOCKSZ = 90, M = N1 + 2*N1/BLOCKSZ, TAIL = 4000 } ;
 const char* const crnl = "\r\n" ;
 typedef std::string::size_type size_type ;
 typedef std::string::iterator iterator ;
 int tick;

 tick=GetTickCount();
 // create a string containing N ' '
 std::string str( N, ' …
Frederick2 189 Posting Whiz

Here is the full code relating to my performance problem I’m having with my operator+= which I described in this adjacent thread….

http://www.daniweb.com/forums/thread340734.html

As a quick review, I’m finding that the operator+= function in the Standard C++ Library’s String Class, i.e., <string>, is performing almost impossibly fast compared to the one in my own String Class, and I’m looking for help or explanations why this is so. In the thread referred to above I provided a stripped down version of my String Class with piles of console output statements in the various implicated String Class member functions to help folks see what is going on, and hopefully provide ideas/comment on which I could work. However, below are four full programs with included performance timings from the Windows Api GetTickCount() function. Included in the programs are output statements which clearly show what is happening rather quickly, and what is taking a lot of time. Before I post the code, however, here is the string algorithm being processed…

'1) Create a 500000 character string of dashes or spaces;
'2) Change every 7th dash or space to a "P";
'3) SEARCH FOR AND Replace every "P" with a "PU" (hehehe);
'4) Replace every dash or space with an "8";
'5) Put in a carriage return & line feed every 90 characters;
'6) Output last 4000 characters.

Here is my first implementation which uses the C++ Standard Library String Class…

#include "windows.h" …
Frederick2 189 Posting Whiz

I don’t know why my operator += and operator + string class member functions are taking so long to do their job and are so inefficient compared to the Standard C++ Library String Class. Its not that they don’t work; its just that they are slower by a factor of like a hundred or thousand or something ridiculous like that. I’m wondering if I’m doing something terribly wrong. I’m hoping that one of the C++ wizards here at Daniweb could take a brief look at my stripped down version of my String Class where I work on a very simple 20 byte long String, i.e., “11111111112222222222”; I dismember it into two 10 byte chunks; then concatenate it back together in a second buffer appending a “\r\n” after each of the two ten byte chunks. In other words, the output from the program is this…

1111111111
2222222222

…in a second buffer.

I’ve included the exact output from this program right beneath it, so you don’t even have to run it. The output includes a voluminous trace file showing in excruciating detail all the String Class Member Function Calls, addresses of everything, etc. Naturally, I have to include my stripped down String Class for anyone who would be willing to run it or examine the code. In my real String Class I use the <tchar.h> macros because I’m a Windows programmer, but I believe that brutality and nastiness is specific to Windows, so I removed it so Unix/Linux …

Frederick2 189 Posting Whiz

I imagine you need to learn how to do it with one of the cross-platform toolkits then. Otherwise, you would need a specific and different implementation for each platform. Win32 is out in that case. You need a higher level abstraction layer on which to work.

Frederick2 189 Posting Whiz

I agree with Ancient Dragon that its fairly easy to do in Win32 (who would want to disagree with Ancient Dragon anyway?)

I call these things 'Custom Controls'. That is perhaps why you can't find any links to this. The term 'widget' is a somewhat 'nix centric expression. In Windows we call them custom controls or ActiveX controls. I have a tutorial here on creating them...

http://www.jose.it-berater.org/smfforum/index.php?topic=2907.0

However, it is in PowerBASIC. Further, however, it is pure Win32. If you understand Win32 you can easily translate it to C. If you don't know Win32 you're dead in the water, unfortunately.

ActiveX controls can be 'cookbooked' with MFC or Atl. However, I tend to write them from scratch using pure Win32. That isn't a casual endeavor, however. If you want, I'll translate thattutorial to C++. You'll have to let me know though.

Frederick2 189 Posting Whiz

I'm a coder that doesn't know much about hardware, but I have a question that's been bugging me for a long, long time.

If I took a pretty new and fast machine (and I'm mostly interested in laptops) such as a recent XP or Win 7 and tried to put an older operating system on it such as Win 2000 or Win 98, what chance is there that I could get a decent display resolution other then the 640 X 480 or whatever it is you get from an OEM install without the specific display driver? Likely the manufacturer's download page wouldn't have drivers for anything other than what they put on the machine, so how generic or specific are these drivers. I really don't have any feel for this. I don't fool with these sorts of things much.

Would this work easier for desktops?

Frederick2 189 Posting Whiz

It compiles and runs vijayan! I'm coming in around 47 ticks. By far best yet. That's awesome code. I'm going to try to figure it out now. I'm very grateful for your time and help. Very.

Frederick2 189 Posting Whiz

Wow Vijayan! Thanks! I'm going to really study that code and see what I can learn from it. I'll see if I can get it to run now.

Frederick2 189 Posting Whiz

I need to ‘come clean’ Vivayan; I’m working on benchmarking various C++ compilers, programming languages, and algorithms, so just generating the last 4000 bytes of that series isn’t my goal. Also, I’m using this exercise to try to improve my knowledge of C++ and particularly String Class construction; String Classes are a particular interest of mine, since I’m an application programmer. My background is more in C and other programming languages than C++. Developing my String Class over the past several years has been a very good learning experience for me, and I have used it very successfully in my Windows CE work.

I’m working very hard on this right now, and if anyone is interested in commenting on what I’m doing or my code I’d appreciate it (maybe there are like minded folks out there!). Here is the PowerBASIC program I’m trying to implement and match as close as possible speed wise in either C or C++. It’ll do this 2MB buffer thing in 0.078 seconds (78 ticks) on my old laptop…

'1)Create a 2MB string of spaces; John Gleason’s original had 15 MB
'2)Change every 7th null to a "P"
'3)replace every "P" with a "PU" (hehehe)
'4)replace every null with an "8"
'5)Put in a carriage return & line feed every 90 characters
'DONE 0.078 secs!

#Compile Exe
#Dim All
Declare Function GetTickCount Lib "KERNEL32.DLL" Alias "GetTickCount" () As Dword

Function PBMain() As Long
  Local i, count7, currPos As Long
  Local s, s1 As String …
Frederick2 189 Posting Whiz

Thanks for the info Narue! That is indeed a critical issue I hadn't thought of!

Frederick2 189 Posting Whiz

Thank You very, very much vijayan21! I've been struggling with this for some time, and that accomplished exactly what I needed!

I might add that that really surprised me. In terms of why, my only possible explanation is that there is a different implementation for operator+ and operator+=??? I wouldn't have thought that!

To be perfectly honest, I never use those compound operators. I just don't like the notation. From seeing this though, if my explanation is anywhere near correct, I'd better start using it if I'm going to use other folk's classes.

In the problem I'm working on (don't know if you are interested), pre-allocating the buffer like that and having it 'stick' decreased my tick count from 402985 to 287922 on this algorithm which allocates and creates a 2MB buffer of '-' chars, replaces every 7th char with a 'P'; then replaces every 'P' with a 'PU'; then replaces every '-' with an '8'; then copies this string in 90 byte chunks to another buffer appending a CrLf to each 90 byte line, and finally outputs the last 4000 bytes to a MessageBox() Whew! I Know! Fairly heavy duty string minipulation....

#include "windows.h"
#include <stdio.h>
#include <string>
#define  NUMBER 2000000  
using namespace std;

string& ReplaceAll(string& context, const string& from, const string& to)
{
 size_t lookHere=0;
 size_t foundHere;

 while((foundHere=context.find(from,lookHere)) != string::npos)
 {
  context.replace(foundHere, from.size(), to);
  lookHere=foundHere+to.size();
 }

 return context;
}

int main(void)
{
 unsigned tick;
 int iCount=0;
 string s2;

 tick=GetTickCount();
 string s1(NUMBER,'-');
 s2.reserve(2200000);
 for(int i=0; …
Frederick2 189 Posting Whiz

Is there a way to pre-specify a specific string buffer size for the underlying buffer
to which repeated concatenations are going to be made in a loop with the purpose of
eliminating time wasting re-allocations and block movements of characters from one
buffer to another? I have tried the string::reserve() member but in my trials at
least it appears useless; the first assignment of a string to an object to which
it was applied results in the string::capacity() being reset to the approximate length
of the string assigned; whatever the original string::reserve() was set to is lost.
Perhaps some kind of 'lock' type capacity, but I don't see anything like that. Here
is an example program showing my problem, as well as its output which shows that my
initial 'reserve()' of 256 bytes is being completely ignored and lost...

#include <stdio.h>
#include <string>
using namespace std;

int main()
{
 string s1[]={"Zero ","One ","Two ","Three ","Four ","Five ","Six "};
 string s2;

 s2.reserve(256);   //Set buffer to 256???
 printf("s2.capacity() = %d\n\n\n",s2.capacity());
 printf("i\ts1.c_str()\n");
 printf("==================\n");
 for(unsigned i=0; i<sizeof(s1)/sizeof(s1[0]); i++)
     printf("%d\t%s\n",i,s1[i].c_str());
 printf("\n\n");
 printf("i\ts2.capacity()\ts2.size()\ts2.c_str()\n");
 printf("=========================================================================\n");
 for(unsigned i=0; i<sizeof(s1)/sizeof(s1[0]); i++)
 {
     s2=s2+s1[i];  //reserve doesn't maintain 256???
     printf("%d\t%d\t\t%d\t\t%s\n",i,s2.capacity(),s2.size(),s2.c_str());
 }
 getchar();

 return 0;
}
s2.capacity() = 256


i       s1.c_str()
==================
0       Zero
1       One
2       Two
3       Three
4       Four
5       Five
6       Six


i       s2.capacity()   s2.size()       s2.c_str()
=========================================================================
0       5               5               Zero
1       10              9               Zero One
2       20              13              Zero One Two
3       19              19              Zero One …
Frederick2 189 Posting Whiz

Ahhh! I got it now! Somehow I switched that around in my mind!!! I really don't do these things all that much, and just got it backward. Thanks FBody and Narue! Really had me mystified!

Fred

Frederick2 189 Posting Whiz

But the results speak for themselves. You can't argue away what the output is. As crazy as it seems, MY THINKING IS BACKWARD.

Frederick2 189 Posting Whiz

Geez, I know darned well disagreeing with you on any C++ matter is a losing proposition Narue, but FBody's idea is the only thing that works in my mind. I mean, this '>>' is right shift right? And right shifting 1000 0000 by 1 bit should give 0100 0000, right? But it doesn't. One must do a left shift on 1000 0000 to get a 2, and a left shift on 1000 0000 should give zero as the left most bit is shifted into nothingness?

Unless I've got the operator - operand thing mixed up.

Frederick2 189 Posting Whiz

I musn't be thinking about something right (or maybe left)! If I have the number '1', which in binary is this...

1000 0000

...and I do a right shift on it to get this...

0100 0000

then that should give me '2', not??? Then why doesn't this work...

#include <stdio.h>

int main(void)
{
 char x=1;

 x=x>>1;
 printf("x=%d\n",x);
 getchar();

 return 0;
}

//x=0

Doesn't x=x>>1 mean 'Shift 1 to the right 1 bit? Isn't that 2? Here is my program to shift 1 across all 8 bits. Notice I'm using left shift - not right shift. That doesn't make sense to me. The output you see below the program is what I want (what I'm wanting to create is an and mask), but I'm having to use the bit shift operator backwards from what I'm thinking it should be. Can someone please set my head right (or left) on this??????!!!!!!

#include <stdio.h>

int main(void)
{
 unsigned char x=1;

 printf("i\t1<<i\n");
 printf("==============\n");
 for(unsigned i=0; i<8; i++)
 {
     x=1<<i;
     printf("%u\t%d\n",i,x);
 }
 getchar();

 return 0;
}



/*
i       1<<i
==============
0       1
1       2
2       4
3       8
4       16
5       32
6       64
7       128
*/
Frederick2 189 Posting Whiz

I find it hard to believe you are finding it hard to find links on ODBC. Here is a Wikipedial link...

http://en.wikipedia.org/wiki/Open_Database_Connectivity

I imagine wxWidgets must have some class wrappers on ODBC. If not you can use what I provided as a start. All those databases you listed in your first post are supported for sure. The beauty of ODBC is that you can use close to the same code for all. I say 'close to the same' because the standards allow for different levels of support. ODBC contains various functions that query the underlying proprietary database driver for functionalities supported. In that way your code can act appropriately to the context of its present environment.

Frederick2 189 Posting Whiz

I've posted various tutorial material on the subject in various places. Here is about the same as I posted here but in C instead of C++, but I believe the code is somewhat more heavily commented...

http://www.powerbasic.com/support/pbforums/showthread.php?t=24912&highlight=ODBC+Demo

And here is a rather complex demo that is GUI but shows how to connect to Microsoft SQL Server, Microsoft Access, and Microsoft Excel. Also, it shows how to use SQLDrivers() to dump the ODBC database drivers on your system....

http://www.jose.it-berater.org/smfforum/index.php?board=378.0

As I mentioned, I never tried it on Linux. I have Ubuntu too; just never checked it out. These ODBC functions (the ODBC Api) should work exactly the same on Linux/Unix as on Windows though. If you get it working with My Sql or anything like that I'd appreciate knowing how to change or add to my cnnection string wrappers so as to include it so to speak. The way things are set up now, I have that MakeConnectionString() function...

void SQL::MakeConnectionString(void)
{
 if(strDriver==_T("SQL Server"))
 {
    if(strDBQ==_T(""))
    {
       strConnectionString=_T("DRIVER=");
       strConnectionString=strConnectionString+strDriver+_T(";")+_T("SERVER=")+strServer+_T(";");
    }
    else
    {
       strConnectionString=_T("DRIVER=");
       strConnectionString=strConnectionString+strDriver+_T(";")+_T("SERVER=")+strServer+_T(";")+ \
       _T("DATABASE=") + strDatabase + _T(";") + _T("DBQ=") + strDBQ + _T(";");
    }
 }
 else if(strDriver==_T("Microsoft Access Driver (*.mdb)"))
 {
    strConnectionString=_T("DRIVER=");
    strConnectionString=strConnectionString+strDriver+_T(";")+_T("DBQ=")+strDBQ+_T(";");
 }
 else if(strDriver==_T("Microsoft Excel Driver (*.xls)"))
 {
    strConnectionString=_T("DRIVER=");
    strConnectionString=strConnectionString+strDriver+_T(";")+_T("DBQ=")+strDBQ+_T(";");
 }
}

where you choose SQL Server, Microsoft Access Driver, or Excel Driver, and that function puts together a connection string. That's the function that needs added to to support other databases.

When I first learned …

Frederick2 189 Posting Whiz

Here's how I'd do it. First make a text file and put about 10 numbers in it and call it Data.txt...

1
5
34
65
2
7
897
123
36
67

#include <stdio.h>
const int SIZE_ARRAY=500;

int main()
{
 int ar[SIZE_ARRAY];
 int iNum=0,iCtr=0;
 FILE* fp=NULL;

 fp=fopen("Data.txt","r");
 if(fp)
 {
    printf("iCtr\tar[iCtr]\n");
    printf("================\n");
    while(true)
    {
       fscanf(fp,"%d",&iNum);
       if(feof(fp))
          break;
       if(iCtr<SIZE_ARRAY)
          ar[iCtr]=iNum;
       printf("%d\t%d\n",iCtr,ar[iCtr]);
       iCtr++;
    };
    fclose(fp);
 }

 return 0;
}

Here's the output...

iCtr    ar[iCtr]
================
0       1
1       5
2       34
3       65
4       2
5       7
6       897
7       123
8       36
9       67

And here's a better version using pointers where you don't have to care about how many items are in the file at all...

//this version dynamically allocates memory for
//number of ints in file Data.txt
#include <stdio.h>

int main()
{
 int* pInt=NULL;
 int iNum=0,iCtr=0;
 FILE* fp=NULL;

 fp=fopen("Data.txt","r");
 if(fp)
 {
    while(true)               //1st find out how many ints in file
    {
       fscanf(fp,"%d",&iNum);
       if(feof(fp))
          break;
       iCtr++;
    };
    pInt=new int[iCtr];       //allocate memory for iCtr ints
    rewind(fp);               //rewind file
    printf("i\tpInt[i]\n");
    printf("===============\n");
    for(int i=0; i<iCtr; i++)
    {
       fscanf(fp,"%d",&iNum);
       pInt[i]=iNum;
       printf("%d\t%d\n",i,pInt[i]);
    };
    fclose(fp);
    delete [] pInt;
 }

 return 0;
}

Output...

i       pInt[i]
===============
0       1
1       5
2       34
3       65
4       2
5       7
6       897
7       123
8       36
9       67

...which is the general way of dealing with this sort of thing, as I originally stated.

Frederick2 189 Posting Whiz

AFAIK, Odbc is not part of C++ standard so it is neither in Mingw or Linux GCC. So where do I download headers/sources to compile? Or even ready .a and .h?

In terms of relational databases, what is in the C++ standard? My guess is nothing, but don't rely on me as being knowledeable about the C++ standard because I've never read it.

Having said that I've never used a Windows computer nor a 32 bit programming language where I couldn't easily use ODBC to connect to relational databases, among other things. I use PowerBASIC a lot...

www.powerbasic.com

and they have headers that allow me to use ODBC. Years ago I used to use the GNU / Bloodshed Dev-C++ and the necessary libs and headers were installed as part of the default install. Likewise Visual Studio 6 (circa 1999), and Visual Studio 2008. I now use the new cross platform Code::Blocks a lot too. That code I just posted was written in CodeBlocks.

The most basic Windows installation will install ODBC drivers for most databases; I'm even pretty sure for Oracle. I wouldn't bet my life on that one, but I've seen Oracle Drivers on my systems, and I've never installed any Oracle products.

I have some programming familiarity with Linux, but I've never done any database work on it, so I can't guide you there. If you are only using Linux, why don't you check the /bin and /lib subdirectories for those …

Frederick2 189 Posting Whiz

Joseph,

The best way to deal with a problem of this sort is to open and close the file twice, or reset the file pointer to the beginning after the 1st read.

The 1st time you read through the file you don't store anything. Its purpose is simply to find how much data is there.

After determining that you read it a second time but this time you only run the loop till you get to the end of the data - which you discovered in your 1st step.

In your case, since you are statically dimensioning an array with a max of 500 elements, if there are more data in the file than 500 you mustn't read beyond 500 or you'll corrupt your memory and likely crash fairly soon after that if not immediately.

Frederick2 189 Posting Whiz

Thanks for not taking it the wrong way what I posted hiddepolen. After I posted it I thought I was being pretty nasty.

The reason I reacted the way I did though is that I've seen folks did themselves into a hole they weren't able to get themselves out of by over concentrating on Dialog Box programming. First thing newcommers start doing is trying to make them the basis of major applications, and they soon run into trouble.

For quick and dirty though, as you discovered, it works.

Frederick2 189 Posting Whiz

In my opinion Windows Drag And Drop Dialog Engine Programming using C++ represents the antithesis of whatever virtue adheres in the language. Might as well just switch to Visual Basic and be done with it.

Frederick2 189 Posting Whiz

hiddepolen, in my opinion what you have just described is the absolute worst way possible to start Win32 programming. It is very quick and dirty, I know. What you have described is use of the Windows Dialog Engine to create an application. Further, you are going to become addicted to 'drag and drop' programming that way. Real programmers start with RegisterClassEx() Frame Windows.

Frederick2 189 Posting Whiz

I'm sure there is an implementation of ODBC for Unix. Its a database standard which applies to all the databases you listed. However, there are various levels of 'conformance' to the standard. That does not mean that some won't work with it, but rather that some optional features might not (most definitely aren't!) be implemented on all databases.

If you have Windows or access to it here is a little program that creates a Microsoft Access database ( a TestData.mdb file ), creates a Table1 in the database, writes a few records to the Table1, then dumps the data. If you have Microsoft Access you can open the database after the program runs. Its named TestData.mdb. It should be in whatever directory you are running the program from. Don't put this code in C:\Program Files or C:\Documents And Setting though. I don't believe it will work. At least not on XP. I'd recommend somewhere right off your C drive such as C:\OdbcDemo or C:\Code\OdbcDemo or something like that. This is a Microsoft thing I can't explain. Oh, one other thing. This program has to link to the two ODBC libraries, which in Visual Studio are ODBC32.lib and ODBCCP32.lib. With CodeBlocks or any of the GNU it will be libODBC32.a and libODBCCP32.a. This is important. It won't compile without static linking to those libs. I'll start posting the code now...

//Main.cpp
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <odbcinst.h>
#include <sql.h>
#include <sqlext.h>
#include "Strings.h"
#include "Sql.h"
#include "SqlProcs.h" …
Frederick2 189 Posting Whiz

I've been using ODBC for years. Its the very lowest level Api you can use. I'm pretty sure all other SQL Relational database access technologies are built on top of it. Perhaps ADO isn't; not sure of that.

Its platform independent. If you use it on Unix/Linux to access a database, and you would later want to access SQL Server or MS Access, there wouldn't probably be too much to change. For these reasons I'd highly recommend it. Far as I know Microsoft is still maintaining it; I think they have to.

Most newer folks don't like it because its procedural. No OOP. I've written very thin class wrappers around it that work very well for me. I have to admit I've never used it with anything other than Microsoft Access and SQL Server, plus some incidental use with Microsoft Excel. If you want my class wrapper to start with I'd be happy to post it. Actually, I'd like to see an example of a connection string for some of those databases you listed.

Frederick2 189 Posting Whiz

Glad it helped! Never heard anything more from the original poster :)

Frederick2 189 Posting Whiz

Well, that did it. I never checked out that selection on the Help menu. That's a real eye opener. There appear to be several million keyboard shortcuts. I wonder if anyone knows them all? Anyway, the magic combination was 'Ctrl Shift F2' -'Bookmark Clear All'. Thank you Mitrmkar, Fbody, and kes166. Now begins a long period of healing of my damaged psyche. Perhaps in the fullness of time I'll be able to use the...

Edit >> Find >> Mark All

menu selection without my fingers, hands and arms locking up in painful spasms as mortal fear grips me.

Frederick2 189 Posting Whiz

Is there any sort of "Clear"-style button in your Find dialog, or perhaps the advanced version of it?

No, nothing like that. I've looked pretty hard for anything. Unbelievable, isn't it?

By the way, I discovered they can be made to go away by just closing the IDE and then reopening the workspace/project. No need to delete the project like I said. That's about the easiest thing to do.

I'll check out those links now...

Frederick2 189 Posting Whiz

Thanks for the input Fbody. Apparently VC6 isn't the same. I tried that. When I go to

Edit >> Bookmarks

I get an empty dialog because the IDE doesn't consider these things as bookmarks I guess. I have VS2008 and CodeBlocks and other newer editors I use, but would you believe I never, ever use either this marking feature or bookmarks because of the fear of this feature burned into my psyche through the old VC6 IDE!!!!

Anyone have a clue how to remove them?

Frederick2 189 Posting Whiz

For the past 12 years I've lived in mortal, cowering, abject fear of one particular feature of the Visual Studio 6 C/C++ IDE, and that is the 'Find' feature on the 'Edit' menu where you can fill in the textbox to find a symbol in your file, and then click the button to 'Mark All'. The IDE then finds the symbols and puts kind of an aqua-marine colored circle next to each found occurance in the left text editor margin. What I've never been able to figure out is how to remove these colored circles once one is through with them. I've tried to solve this riddle countless times and always fail. What I find I must do is copy the files to somewhere else, completely delete the whole project, then recreate it and add the files back. Unbelievable, I know. Today I did the unthinkable, and used this feature. I spent a half hour trying to figure it out and finally gave up in the hope someone here knows the magic combination. Otherwise its there permanently unless I delete the project. I fully realize this is completely ridiculous, but I've gotta tell you, I've no idea how to do this.

Frederick2 189 Posting Whiz

Lot of info here too. I prefer base pointer notation in working with VPTRs ant VTables...

http://www.jose.it-berater.org/smfforum/index.php?topic=2980.0

Frederick2 189 Posting Whiz

To show an additional 'Form' from an Sdk style program you 1st register a class for the form (window) (you'll also need a window procedure specific to that new form's Window Class), call CreateWindowEx() on the new class, and finally, ShowWindow() it. Whether the CreateWindow/ShowWindow calls are in the event handler for a menu selection, a button, whatever, doesn't matter.

Frederick2 189 Posting Whiz

Haah! I was right all along! I just did a search over in the CodeBlocks forum and came up with this...

http://forums.codeblocks.org/index.php/topic,11335.0.html

Talk about a 'gotcha'! In GCC if a dll is compiled as a C++ program DllMain() is mangled and the internal fabricated DllMain will be called instead of the one in one's code. The trick is to prepend an extern "C" to DllMain()!!!!

Below is a dll and host recoded to show what works. Hopefully, if anybody else runs into this problem they will find this topic (I lost more than a day on this!).

//Example Dll
#include <windows.h>
#include <stdio.h>
FILE* fp=NULL;

extern "C" void __declspec(dllexport) SomeFunction(const char* szBuffer)
{
 printf("%s\n",szBuffer);
}

extern "C" BOOL __stdcall DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
 switch(fdwReason)
 {
  case DLL_PROCESS_ATTACH:
       puts("In DLL_PROCESS_ATTACH");
       fp=fopen("Output.txt","w");
       fprintf(fp,"In DLL_PROCESS_ATTACH\n");
       fclose(fp);
       break;
  case DLL_PROCESS_DETACH:
       fp=fopen("Output.txt","a");
       puts("In DLL_PROCESS_DETACH");
       fprintf(fp,"In DLL_PROCESS_DETACH\n");
       fclose(fp);
       break;
 }

 return TRUE;
}
//Example Host With Console/File Output
#include <stdio.h>
extern "C" __declspec(dllimport) void SomeFunction(char*);

int main()
{
 SomeFunction("Hello, World!");
 getchar();

 return 0;
}


/*
Display
=====================
In DLL_PROCESS_ATTACH
Hello, World!


File
=====================
In DLL_PROCESS_ATTACH
In DLL_PROCESS_DETACH
*/
Frederick2 189 Posting Whiz

My title says it all! I'm completely mystified by this - have been working at it all day with no resolution.

The fundamental assumption under which I am laboring is that when a Dll is loaded into a host's process, the Dll will receive a DLL_PROCESS_ATTACH message. I have been working with Dlls for years and have never had a problem with this. Frequently I'll put code in a DLL_PROCESS_ATTACH handler to open a debug log file if a #define such as MYDEBUG is defined. In most cases a person can even get away with putting a MessageBox() in DLL_PROCESS_ATTACH although the MSDN docs warn against putting any code in DLL_PROCESS_ATTACH that calls anything but kernel functions.

Are there any compilation/linking switches that specify that a dll is not to receive typical dll messages such as DLL_PROCESS_ATTACH?

I have been fooling with several development environments and computers in my attempt to get to the bottom of this. Where I ran into this problem is just recently I converted a very large (large by my standards - maybe 20,000 lines of code) eMbedded Visual C++ Windows CE project to Visual Studio 2008 C++. In that project I have several custom grid controls I wrote in a Dll. Everything works fine there and I can now run the project on desktop Windows. I decided to see if I could get the project running using GCC and CodeBlocks. I got everything to compile finally but when I tried to run …

Frederick2 189 Posting Whiz

Here's a twist then I thought of after my original post. Lately I've been switching a lot between ansi and unicode, and going through replacing wchar_t type stuff with the t macros in tchar.h. When I come to lines such as this...

memset(pBuffer, '\0', iSomeCount);

I was tempted to do this...

memset(pBuffer, _T('\0'), iSomeCount);

...simply because I was going through a lot of code changing "some text" type stuff to _T("some text"). But using AncientDragon's line of reasoning I'm assumming a double NULL, i.e., "00" would be interpreted as just one numeric zero. Right?

Frederick2 189 Posting Whiz

Thanks Mike. Just wanted to make sure. Can't be too careful, it seems!

Frederick2 189 Posting Whiz

The memset function declared in memory.h is declared this way...

void* memset(void* dest, int c, size_t count);

and the MSDN example of its use I have shows this for setting the 1st four bytes of a buffer to a '*'...

memset(buffer, '*', 4);

The 2nd parameter confuses me a bit because its typed as an int which is a 32 bit quantity in 32 bit Windows, yet the example above shows a literal char being used. I frequently use this function and that always confuses me. I frequently use it to zero out a buffer, and I do this...

memset(szBuffer, '\0', iSomeCount);

Is that correct?

What about just this...

memset(szBuffer, 0, iSomeCount);

Are these equivalent? Is one form preferable to the other? Is one or the other incorrect?

Frederick2 189 Posting Whiz

The compiler pays very little attention to the type of the variable on the left side of an assignment statement until the assignment actually begins.

That does appear to be about the best description of the situation. Your constant mentioning of the operator overloading issue (obviously different code is being generated for the different situations) prompted me to check out what happens in the case of compiling as a C program but the outcome was the same.

After I discovered what was happening in my code and that I could solve the problem by casting either of the parameters (divisor??? dividend??? - my memory fails me!), I thought a more correct cast would be this...

dblFactor = (double)(iNum1 / iNum2);

...but of course that failed too for the reasons you described; 1st a truncation to zero then the assignment of the zero to dblFactor. As you say, the compiler is looking for a double in either the top or bottom or both.

Oh well, now I know!

Frederick2 189 Posting Whiz

Yes, I see now. In your example you are using hard coded literals, i.e., 5.0, etc. In my actual program where this bit me (complex code and it took me a good hour to track it down) I have all variables. Here is the actual statement which was giving me zeros for everything...

dblFactor = ptrMainWindowData->ConfigData.BAF / iPlots; //both integers

I'm not new to C++; I guess I don't use floating points very much; mostly GUI code. It just really astounded me to see that.