0

I need to pack this pointer (which is 64 bits wide) into 4 WORD's, and then later in some other part of the code I need to extract (assemble) these words back into this pointer.

the code looks like this:

std::vector<WORD> vec;
vec.push_back( this ); // how?

later in the code;

pThis = vec.at(0); // how?

I did take a look at LOWORD/HIWORD and LOWBYTE/HIBYTE macros however I still have no idea how would I go about this.

If you ask why on earth would anyone need this, here is why: I need to fill in creation data of DLGITEMTEMPLATEEX structure which takes WORD as last argument to specify size, data following this is where you put your data, my data is this pointer, and since I'm working on words (std::vector<WORD>) to fill the structure, the last data is 4 WORDS (64 bits) representing the pointer!

Any suggestion or sample code is welcome.

metablaster
  • 1,958
  • 12
  • 26
  • 1
    `memcpy(&vec[0], &this, sizeof(this));` and then `memcpy(pThis, &vec[0], sizeof(your_class*));`. Still the link doesn't explain why you want to use 4 WORDS (why 4?) and not just a pointer. You probably mean to just `struct my_struct { DLGITEMTEMPLATEEX template; your_class *pThis; }` and then use `containerof` (or just cast the pointer) to get `pThis`. – KamilCuk Nov 03 '19 at 20:49
  • 1
    @KamilCuk You are missing a `&` before `pThis`. – walnut Nov 03 '19 at 20:51
  • great I'll try out this code, btw, `DLGITEMTEMPLATEEX ` is a special non existent structure, we need to fill it in the memory. and then pass a pointer to memory to functions which expect `DLGITEMTEMPLATE*` structure. I use vector to avoid `C style` – metablaster Nov 03 '19 at 20:51
  • See also `DWORD_PTR` https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-dtyp/66d61dd8-2191-4a37-b963-e49bf0dc2579 – Richard Critten Nov 03 '19 at 20:51
  • It might be better to maintain a separate mapping between dialog items and your objects. You can use the control ID as the key. – rustyx Nov 03 '19 at 20:56
  • @rustyx that would be great but how? `DLGITEMTEMPLATE` must be appended to the end of `DLGTEMPLATEEX ` I don't see any documentation to separate this for "memory dialogs" `DLGITEMTEMPLATE` already makes use of control ID's and adding controls to dialog template can't be done separately. only in memory before creation – metablaster Nov 03 '19 at 21:02
  • @KamilCuk 4 WORD's because address value of a pointer is 64 bit value. – metablaster Nov 03 '19 at 21:08
  • what a disastrous API definition – M.M Nov 03 '19 at 21:46
  • 1
    Dialogs are normally created from resource files. In the rare case that you need to *generate* dialogs dynamically (why?), have a look at [this](https://stackoverflow.com/questions/61634/windows-api-dialogs-without-using-resource-files). In any case, the interface between the dialog and the rest of the application goes via messages and control IDs. So there is no need to append anything to the dialog item structure, as it will be of no use. – rustyx Nov 03 '19 at 22:20
  • @rustyx thanks a lot for link, I didn't know we can create a dialog before adding controls to it. I used `DialogBoxIndirectParamW` instead of `CreateDialogIndirectParamW` huge difference! I create dialogs in memory because that's the most flexible for reusable GUI API I'm working on. – metablaster Nov 03 '19 at 23:32
  • [`std::bit_cast`](https://en.cppreference.com/w/cpp/numeric/bit_cast). – IInspectable Nov 04 '19 at 12:47

2 Answers2

0

Well, the best way would be to define a struct that derive form DLGITEMTEMPLATEEX. That way, you can avoid to manually do the conversion. While it might not be defined from the standard, it will works on Windows. That kind of code if platform specific anyway!

struct MyTemplate : DLGITEMTEMPLATEEX
{
    MyTemplate(MyPointerType *myVariable) 
        : extraCount(sizeof *this - sizeof(DLGITEMTEMPLATEEX))
        , myVariable(myVariable)
    { }

    MyPointerType *myVariable; // 64 if compiled for 64 bit target.
};

And when using the data, you do a static_cast to convert back to that structure.

You could add a few static_assert and assertion to validate that it works as intended.

Phil1970
  • 2,605
  • 2
  • 14
  • 15
  • 1
    Why would this not be well defined per the C++ language? `DLGITEMTEMPLATEEX` is a [standard-layout class](https://en.cppreference.com/w/cpp/language/data_members#Standard_layout). – IInspectable Nov 04 '19 at 12:51
0

You could use simple bitshifting to seperate the 64bit into 16bits.

#include <stdio.h>

int main(){
    uint64_t bigword = 0xDEADBEEFADEADBED;
    uint16_t fourth = bigword ;
    uint16_t third = bigword >> 16;
    uint16_t second = bigword >> 32;
    uint16_t first = bigword >> 48;
    printf("%llx %x %x %x %x\n",bigword,fourth,third,second,first);
    return 0;
}

Then reverse the process when shifting the words back into the 64bit.

Irelia
  • 3,407
  • 2
  • 10
  • 31