Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

SetWindowText with different number systems

Posted on 2006-06-10
7
Medium Priority
?
523 Views
Last Modified: 2012-06-21
Hi all,

I'm trying to figure out how to display the contents of a BYTE array using SetWindowText in different number systems such as decimal, hex and binary.  I've used sprintf in this regard but with no success. As SetWindowText prefers char arrays, I'm trying to rack my brains for a way to accomodate it.  Could anyone help me?

Thanks

pushpop
0
Comment
Question by:pushpop
  • 2
  • 2
  • 2
  • +1
7 Comments
 

Expert Comment

by:sambitdash
ID: 16881197
My windows has gone a bit rusty but my understanding is

BYTE is defined as unsigned char.

While SetWindowText may be looking for a char* pointer. Just cast your BYTE array as (char*) everything will work fine.
0
 

Author Comment

by:pushpop
ID: 16881235
Hmmm, i tried that but to no avail! You'll probably get a better idea of what I'm doing wrong if I give you the source!


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

#include <windows.h>                  /*defines all window related bits of code*/
#include <stdio.h>
#include "resource.h"                  /*defines the messages for the window*/
#define _WIN32_WINNT 0x0501

#define WIN32_LEAN_AND_MEAN

HWND wnd,fsbox,rawbox,drvlbl,serbox,mounted_drives,combo;   /*the various handles to our windows*/
HANDLE hfile;                            /*file descriptor/handle/whatever*/

HINSTANCE hInstance;                  /*program instance handle*/
BYTE buffer[513];                        /*temporary buffer*/
char * dest;
int bytesRead,i,NTFS,FAT;
LPVOID lpMsgBuf;
char * vp;
char tmp [5];
char * drive = "\\\\.\\C:";      /*the drive we want to examine*/
char mountedDrives[26];

LRESULT CALLBACK DlgProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);

void readNTFS();
void readFAT();
void getDrives();


struct NTFSboot
{
            char jmp_instr [3];
            char byters_Per_Sector[2];
            char secs_Per_Cluster;
            char med_desc ;
            char total_secs [8];
            unsigned long serial_num;
            char MFT_start [8];
};                                                                        


typedef struct NTFSboot NTFSboot;
NTFSboot nb;


/*program entry point*/
INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine, int nCmdShow)
{
    DialogBox(hInstance, MAKEINTRESOURCE(main_mnu),
                wnd, (DLGPROC)DlgProc);

    return 0;
}


LRESULT CALLBACK DlgProc(HWND hWndDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
{
      switch(Msg)
      {
      case WM_INITDIALOG:
      
            dest = (char *)malloc(520);
            dest = (char *)buffer;
            fsbox = GetDlgItem(hWndDlg,fs_box);
            rawbox = GetDlgItem(hWndDlg,raw_box);
            drvlbl = GetDlgItem(hWndDlg,drv_lbl);
            serbox = GetDlgItem(hWndDlg,serial_box);
            combo = GetDlgItem(hWndDlg,combobox);
            mounted_drives = GetDlgItem(hWndDlg,mounted);
            getDrives();
            
            if((hfile = CreateFile(drive,GENERIC_READ,                                    /*get a handle to our drive*/
                     FILE_SHARE_READ|FILE_SHARE_WRITE,
                     NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
                     NULL))==NULL)
            {
                               FormatMessage(
                         FORMAT_MESSAGE_ALLOCATE_BUFFER |
                         FORMAT_MESSAGE_FROM_SYSTEM |
                         FORMAT_MESSAGE_IGNORE_INSERTS,
                         NULL,
                         GetLastError(),
                         0,
                         (LPTSTR) &lpMsgBuf,
                         0,
                         NULL );
                         MessageBox( NULL, (LPCSTR)lpMsgBuf, "Problem acquiring handle to disk", MB_OK | MB_ICONWARNING );
                         
                                     EndDialog(hWndDlg, 0);
                                   return FALSE;
            }

            if(ReadFile(hfile,buffer,512,&bytesRead,NULL)==FALSE)       /*read MBR or give err msg and die*/
               {
                         FormatMessage(
                         FORMAT_MESSAGE_ALLOCATE_BUFFER |
                         FORMAT_MESSAGE_FROM_SYSTEM |
                         FORMAT_MESSAGE_IGNORE_INSERTS,
                         NULL,
                         GetLastError(),
                         0,
                         (LPTSTR) &lpMsgBuf,
                         0,
                         NULL );
                         MessageBox( NULL, (LPCSTR)lpMsgBuf, "Disk read error!", MB_OK | MB_ICONWARNING );
                         EndDialog(hWndDlg, 0);
                                     return FALSE;
                                     
                   
               }

            for (i=0; i<bytesRead; i++)  /*zap any null terminators*/
            {
                  if (buffer[i] < 0x20)
                  buffer[i] = '.';
            }
            
            
            

            /* nice function which displays the filesystem as
             * FAT **correctly** regardless of which edition it is
             */
            if(vp = strstr(buffer,"FAT"))
            {
                  memcpy(tmp,vp,5);
                  SetWindowText(fsbox,tmp);
                  FAT = 1;
                  //readFAT();
                  
            }

            

            else if(strstr(buffer,"NTFS"))
            {
                  SetWindowText(fsbox,"NTFS");
                  NTFS = 1;
                  readNTFS();
                  
            }      
            else
            {
                  MessageBox( NULL, "DiskUtil doesn't recognise this type of disk\n"
                                            "continuing on with analysis will\n"
                                            "yield inaccurate results, so the program will now exit"
                                            ,"Disk read error!", MB_OK | MB_ICONWARNING );
                                            EndDialog(hWndDlg, 0);
                                            return TRUE;
            }

            sprintf(dest,"%x",dest);
            SetWindowText(rawbox,dest);
            SetWindowText(drvlbl,drive);
      case WM_COMMAND:
            switch(wParam)
            {
            case IDOK:
                  EndDialog(hWndDlg, 0);
                  return TRUE;
            }
            break;
      }

      return FALSE;
}


void readNTFS()
{
   


}

void readFAT()
{

}


void getDrives()    /*detect all the mounted drives in a system*/
{
      char root_path[8];
      char vol_name[MAX_PATH+1];
      DWORD max_comp_len;
      DWORD fs_flags;

      for(i = 'A';i < 'Z';i++)
      {
            sprintf(root_path,"%c:\\ ",i);
            if(GetVolumeInformation(root_path, vol_name, MAX_PATH, 0, &max_comp_len, &fs_flags, 0, 0))
                  strcat(mountedDrives,root_path);
            
                  SetWindowText(mounted_drives,mountedDrives);
            

            

      }
      
}
0
 

Expert Comment

by:sambitdash
ID: 16892080
your WM_INITDIALOG falls through WM_COMMAND as well. I guess there should be break. Is it intentional?
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
LVL 14

Accepted Solution

by:
wayside earned 252 total points
ID: 16893997
To convert a BYTE array of binary data into something human-readable, you have to interate over the array and convert each byte and put it into another buffer:

char outputstr[2000] = { 0 };

for (int i=0; i<bytesRead; i++) {
   int outlen = strlen(outputstr);
   sprintf(&outputstr[outlen], "%d ", buffer[i]; // decimal
   sprintf(&outputstr[outlen], "%x ", buffer[i]; // hex

   // binary is trickier
   sprintf(&outputstr[outlen], "%d%d%d%d%d%d%d%d ", (buffer[i] & 0x80) >> 7, (buffer[i] & 0x40) >> 6,
                                                                                    (buffer[i] & 0x20) >> 5, (buffer[i] & 0x10) >> 4,
                                                                                    (buffer[i] & 0x08) >> 3, (buffer[i] & 0x04) >> 2,
                                                                                    (buffer[i] & 0x02) >> 1, (buffer[i] & 0x01));
}

 SetWindowText(rawbox, outputStr);

BTW:

         sprintf(dest,"%x",dest);

It is generally a bad idea to overwrite the input buffer in sprintf. You can wind up crashing.
0
 
LVL 39

Assisted Solution

by:itsmeandnobodyelse
itsmeandnobodyelse earned 248 total points
ID: 16895732
>>>>          dest = (char *)malloc(520);

if you are allocating a char buffer by using malloc you shouldn't overwrite the only pointer to that piece of memory by

>>>>          dest = (char *)buffer;

cause the storage never can be used again (what is called a leak). I would say you should remove the malloc statement cause you don't need it.


>>>>                if (buffer[i] < 0x20)
>>>>                   buffer[i] = '.';
 
No!!! If you replace any non-printable char by a dot you'll never see a reasonable output beside of the few strings. Throw that loop away it's rubbish.

I know, you made that loop because strstr wouldn't find "FAT" or "NTFS" if the buffer contains binary zero characters prior to the text. So, you have to implement the find function yourself. As we are in the C++ TA here, I show you a C++ solution (though it might get lonesome among all that pure C hack you've written above).

#include <string>
using namespace std;

struct Buffer
{
     char buf[512];   // that is the buffer, you don't need any extra byte
     unsigned char* getByteBuffer() { return (unsigned char*) buf;

     // returns the position of the found string or -1 if not found
     int  findString(const char* psz)
     {
            string s = psz;
            string b(buf, sizeof(buf));
            int pos = 0;
            if ((pos = b.find(s)) != string::npos)
                return pos;
            return -1;
     }
     // Note, std::string doesn't care for binary data - hopefully

     
}

You would use the Buffer struct like

    HINSTANCE hInstance;               /*program instance handle*/
    Buffer buffer;                    /*temporary buffer*/

      ...
          if(ReadFile(hfile,buffer.getByteBuffer(),512,&bytesRead,NULL)==FALSE)       /*read MBR or give err msg and die*/
         
          ...

        /* nice function which displays the filesystem as
           * FAT **correctly** regardless of which edition it is
           */
          int pos;
          if( (pos = buffer.findString("FAT")) >= 0)
          {
               string fat( buffer.buf + pos, 5);
               SetWindowText(fsbox, fat.c_str());
               FAT = 1;
               //readFAT();
               
          }
          ...        

Alternatively you could modify the Buffer::findString function to return a 5 byte string instead of a position:

     ...
     string findString(const string& s, int len = -1)
     {
           if (len <= 0)
               len = s.length();
            string b(buf, sizeof(buf));
            int pos = 0;
            if ((pos = b.find(s)) != string::npos)
                return b.substr(pos, len);
            return "";
     }
     ...

Then, the find call would turn to

          string fat = buffer.findString("FAT", 5));
          if (!fat.empty())
          {
               SetWindowText(fsbox, fat.c_str());
               FAT = 1;
               //readFAT();
          }


You easily could add output functions to the Buffer struct, e. g. to get a hex (raw) output like that

 0 |  00 10 C0 80 00 00 01 03 00 02 46 41 54 33 32 00  ..À€....FAT32.
 1 |  00 00 00 00 00 01 00 00 00 03 03 7F 00 00 7E 00  ...............~.
     ...
16|  00 00 00 00 00 01 00 00 00 03 03 7F 00 00 7E 00  ...............~.


You would need an output window (rawbox) that supports multiline.

Tell me if you want to go that way.

Regards, Alex
 
0
 

Author Comment

by:pushpop
ID: 16896538
Hi Guys,

I've split the points between you two as your answers were both equally useful. I hope that's ok. I'd just like to point a few things out-

1. I'm a student so I'm quite new to win32 and self-taught
2. I had to basically teach myself C/C++ as I had two very good semesters of Java and one mediocre one of C++ which barely even mentioned pointers.
3. It's quite discouraging to have your code described as 'hack,' given the above points I've just made. If I'm doing something that could be done better in a different way, I'm all for hearing about it, but I'm not paying a subscription to this site so I can have derogatory comments thrown at me :-)

Thanks again guys

P
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 16899991
>>>> It's quite discouraging to have your code described as 'hack,'

Actually, I didn't want to blame *you* as I recognized very well that you are a beginner. But the code above isn't good - even if looking at it from a C point of view. And I thought that a big part of the code was copied from a C sample. Unfortunately, nearly all samples of native Windows programming were written in C, what makes it very difficult for beginners to apply OO techniques or learn C++ by writing those kind of programs.

I asked you "Tell me if you want to go that way" cause I would like to help you changing the prog above from a badly written C program to a fairly well written C++ program.

Regards, Alex
0

Featured Post

Hire Technology Freelancers with Gigs

Work with freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely, and get projects done right.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Often, when implementing a feature, you won't know how certain events should be handled at the point where they occur and you'd rather defer to the user of your function or class. For example, a XML parser will extract a tag from the source code, wh…
This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

886 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question