Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - 85

#111
Programación C/C++ / Clases de almacenamiento
26 Marzo 2013, 22:38 PM
Hola me decidí a crear un proyecto simple que trate de aplicar todas las keywords del lenguaje con respecto a las clases o directivas de almacenamiento. No creo haber utilizado todos los casos posibles, pero me parece que el resultado es un código que explica muy bien al menos como usar los  casos más generales.
Las keywords en cuestión son estas:

extern
static
auto
register
inline
mutable
volatile


No me pregunten sobre 'mutable' y 'volatile' porque no las he usado nunca XD.

El programa trata de mostrar información por pantalla para dejar en claro el lugar de almacenamiento de las variables utilizadas, y su valor de inicialización.
También se deja en claro el uso de estas directivas en funciones.

Otra cosa que quiero aclarar que 'extern' es por defecto, pero yo lo especifiqué explícitamente para esta demostración.

Y también muestro una forma de usar una función que normalmente no se puede usar de un archivo fuente a otro, pero mediante su dirección se puede.

Dejo el código.

main.cpp
Código (cpp) [Seleccionar]

//
// By 85
// elhacker.net
// etalking.com.ar
// boyscout_etk@hotmail.com
// 2013
//

////////////////////////////////////////////////////////////////////////////////////////////////

#include<windows.h>
#include<stdio.h>

#include "inclusiones.h"

////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////

char* palabra[] = { "Hola", "Mi", "Nombre", "Es", "David", "Y", "El", "Tuyo?" };

char* msgList[] = {

   "HAHAHA",
   "HOHOHO",
   "HUHUHU",
   0
};

char* cadenaCortada = "Hola\nMe\nDices\nTu\nNombre\n?\0";

////////////////////////////////////////////////////////////////////////////////////////////////

extern int variable1;
extern int variable2 = 0;
int variable3        = 0;// Es extern por defecto!, aunque no se especifique

extern char cadena1[] = "AAAAAAAAAAAAAAA";
extern char cadena2[] = "AAAAAAAAAAAAAAA";
char cadena3[] =        "BBBBBBBBBBBBBBB";

static int x;
static int y = 0;

////////////////////////////////////////////////////////////////////////////////////////////////
// MAL! (Revisar los conceptos de cada clase de almacenamiento)

//auto int varmal1;
//auto int varmal2=0;

//register int varmal3;
//register int varmal4=0;

////////////////////////////////////////////////////////////////////////////////////////////////

//Mutable sólo puede ser aplicada a miembros de clases
//Sirve para que determinados miembros de un objeto de una estructura o
//clase declarado como constante, puedan ser modificados.

////////////////////////////////////////////////////////////////////////////////////////////////

//Volatile se usa con objetos que pueden ser modificados desde el exterior del programa,
//mediante procesos externos.
//Es frecuente encontrar juntos los modificadores volatile y const:
//si la variable se modifica por un proceso externo, no tiene mucho sentido que el
//programa la modifique.

volatile int varilo1;
volatile int varilo2 = 0;

volatile int  ilvolo1 = 10;
//int*          p_ilvolo1 = &ilvolo1;// MAL!
volatile int* p_ilvolo1 = &ilvolo1;

////////////////////////////////////////////////////////////////////////////////////////////////
// HACK

// El hack consiste en guardar las direcciones de las funciones 'static' y usar
// punteros a función en las otras unidades de compilación.
// De esa forma, el compilador no lo restringe.

DWORD add_Func1_StringCompare = (DWORD)&Func1_StringCompare;
DWORD add_Func2_StringLength = (DWORD)&Func2_StringLength;
DWORD add_Func3_StripReturn = (DWORD)&Func3_StripReturn;

////////////////////////////////////////////////////////////////////////////////////////////////

static int Func1_StringCompare(char* q, char* a)
{
    do
    {
       if( *q!=*a )
            return -1;
if( !*q )
    break;
q++;
        a++;
    } while( *q );
    return 0;
}

////////////////////////////////////////////////////////////////////////////////////////////////

static unsigned int Func2_StringLength(const char* f){
     
INT i=0;
       while(*f++) i++;
       return i;
}

////////////////////////////////////////////////////////////////////////////////////////////////

static void Func3_StripReturn(char* str)
{
for(register unsigned int i=0;i<strlen(str);i++)
if (str[i]==10 || str[i]==13) {
str[i]=' ';
}
}

////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////

void inline Func4_MostrarCadenas1(){// Inline es sólo para funciones

for(int i=0; i<(sizeof(palabra)/sizeof(palabra[0])); ++i)
{
printf("%d = %s\n", i, palabra[i]);
}
}

////////////////////////////////////////////////////////////////////////////////////////////////

inline void Func5_MostrarMensajes1(){// Inline es sólo para funciones

for(char** i = msgList; *i; i++)
{
MessageBox(0, *i, *i, 0);
}
}

////////////////////////////////////////////////////////////////////////////////////////////////

extern void Func6_getRAM(char* buf){

MEMORYSTATUS Status;
       ZeroMemory(&Status, sizeof(Status));
       Status.dwLength = sizeof(Status);
       GlobalMemoryStatus(&Status);
       DWORD dwRAM = (DWORD)(Status.dwTotalPhys/(1024*1024));
       wsprintf(buf, "%d MB", dwRAM);
}

////////////////////////////////////////////////////////////////////////////////////////////////

void Func7_Variables1(){

// Valores de inicio y lugar de almacenamiento de las variables
//

putchar(10);

int var1;
int var2 = 0;
static int var3;
static int var4 = 0;
volatile int var5;
volatile int var6=0;

printf("variable local sin inicializar:        %d\n", var1);
printf("variable local inicializada:           %d\n", var2);
printf("variable local static sin asignar:     %d\n", var3);
printf("variable local static asignada:        %d\n", var4);
printf("variable local volatile sin asignar:   %d\n", var5);
printf("variable local volatile asignada:      %d\n", var6);
// printf("variable global sin asignar:           %d\n", variable1);
printf("variable global asignada.              %d\n", variable2);
printf("variable global asignada:              %d\n", variable3);
printf("variable global static sin asignar:    %d\n", x);
printf("variable global static asignada:       %d\n", y);
printf("variable global volatile sin asignar:  %d\n", varilo1);
printf("variable global volatile asignada:     %d\n", varilo2);


printf("add variable local sin inicializar:        0x%X\n", &var1);
printf("add variable local inicializada:           0x%X\n", &var2);
printf("add variable local static sin asignar:     0x%X\n", &var3);
printf("add variable local static asignada:        0x%X\n", &var4);
printf("add variable local volatile sin asignar:   0x%X\n", &var5);
printf("add variable local volatile asignada:      0x%X\n", &var6);
// printf("add variable global sin asignar:           0x%X\n", &variable1);
printf("add variable global asignada.              0x%X\n", &variable2);
printf("add variable global asignada:              0x%X\n", &variable3);
printf("add variable global static sin asignar:    0x%X\n", &x);
printf("add variable global static asignada:       0x%X\n", &y);
printf("add variable global volatile sin asignar:  0x%X\n", &varilo1);
printf("add variable global volatile asignada:     0x%X\n", &varilo2);


// El problema con la variable1 es que al haber usado 'extern' y no haberle
// hecho una asignación de valor. el compilador entiende que se hace referencia
// a una variable que está declarada en otra unidad de compilación.
}

////////////////////////////////////////////////////////////////////////////////////////////////

void Func8_Variables2(){

// Valores de inicio y lugar de almacenamiento de las variables
//

putchar(10);

// Se crean y destruyen automáticamente (no se necesita especificar)
auto int varbien1;
auto int varbien2=0;

// Si es posible, se van a almacenar en algún registro del CPU para tener
// un acceso más rápido a ellas. (Tamaño adecuado para entrar en un registro!)
register int varbien3;
register int varbien4=0;

printf("variable local auto sin asignar:      %d\n", varbien1);
printf("variable local auto asignada:         %d\n", varbien2);
printf("variable local register sin asignar:  %d\n", varbien3);
printf("variable local register asignada:     %d\n", varbien4);

auto int var1 = 85;
auto int var2 = var1;
printf("var1: %d   add: 0x%X\n", var1, &var1);
printf("var2: %d   add: 0x%X\n", var2, &var2);

register int var3 = 85;
// Si estubiera en un registro no se obtendría una dirección de memoria!
printf("var3: %d   add: 0x%X\n", var3, &var3);

register int i;
// register int i=0;
for(i=1; i<=10; i++){
if(i==1) printf("add i: 0x%X\n",&i);
printf("%d",i);
}
putchar(10);
}

////////////////////////////////////////////////////////////////////////////////////////////////

static void Func9_dummy1(register int* x){

printf("x: %d   add: 0x%X\n", *x, &x);
}

////////////////////////////////////////////////////////////////////////////////////////////////

static void Func10_dummy2(register int y){

printf("y: %d   add: 0x%X\n", y, &y);
}

////////////////////////////////////////////////////////////////////////////////////////////////

static void Func11_dummy3(volatile int z){

printf("z: %d   add: 0x%X\n", z, &z);
}

////////////////////////////////////////////////////////////////////////////////////////////////
// Retorna un INT volatile, sólo se aplica al tipo de retorno.

volatile int Func12_dummy4(int arg){

int res = arg;
return res;
}

////////////////////////////////////////////////////////////////////////////////////////////////

void Func13_Argumentos(){

putchar(10);

int a = 500;
Func9_dummy1(&a);

int b = 1000;
Func10_dummy2(b);

int c = 5000;
Func10_dummy2(c);

int d = 100000;
Func11_dummy3(d);

int e = Func12_dummy4(15);
printf("%d\n", e);
}

////////////////////////////////////////////////////////////////////////////////////////////////

int main(){

Func4_MostrarCadenas1();
Func5_MostrarMensajes1();

// Cualquiera de las 2 formas (con o sin extern, es lo mismo)
extern void Test1_UnidadDeCompilacion1();
extern void Test2_UnidadDeCompilacion1();
extern void Test3_UnidadDeCompilacion1();
extern void Test1_UnidadDeCompilacion2();
extern void Test2_UnidadDeCompilacion2();
void Test3_UnidadDeCompilacion2();

Test1_UnidadDeCompilacion1();
Test2_UnidadDeCompilacion1();
Test3_UnidadDeCompilacion1();
Test1_UnidadDeCompilacion2();
Test2_UnidadDeCompilacion2();
Test3_UnidadDeCompilacion2();

Func8_Variables2();

Func3_StripReturn(cadenaCortada);
printf("%s\n",cadenaCortada);
system("pause");
return (0);
}


unidad_comp1.cpp
Código (cpp) [Seleccionar]

//
// By 85
// elhacker.net
// etalking.com.ar
// boyscout_etk@hotmail.com
// 2013
//

////////////////////////////////////////////////////////////////////////////////////////////////

#include<windows.h>
#include<stdio.h>

#include "inclusiones.h"

////////////////////////////////////////////////////////////////////////////////////////////////

int (*Ptr_Func1_StringCompare)(char*, char*);

////////////////////////////////////////////////////////////////////////////////////////////////

extern void Test1_UnidadDeCompilacion1(){

// Los externs en este caso son locales a esta función.
extern void Func6_getRAM(char* buf);

char TotalRAM[256] = "";
       Func6_getRAM(TotalRAM);
putchar(10);
       printf("Test1_UnidadDeCompilacion1: Total RAM: %s\n", TotalRAM);
}

////////////////////////////////////////////////////////////////////////////////////////////////

extern void Test2_UnidadDeCompilacion1(){

// Los externs en este caso son locales a esta función.
extern DWORD add_Func1_StringCompare;
extern char cadena1[];
extern char cadena2[];
extern char cadena3[];

putchar(10);

Ptr_Func1_StringCompare = (int(*)(char*, char*))add_Func1_StringCompare;

//if(Func1_StringCompare(cadena1, cadena2) == 0)// No se puede!
if(Ptr_Func1_StringCompare(cadena1, cadena2) == 0)
{
printf("Test2_UnidadDeCompilacion1: IGUALES\n");
}

// No se puede! porque getRam no es un extern "global" en esta unidad de compilación.
//char TotalRAM[256] = "";
       //Func6_getRAM(TotalRAM);
       //printf("Total RAM: %s\n", TotalRAM);
}

////////////////////////////////////////////////////////////////////////////////////////////////

extern void Test3_UnidadDeCompilacion1(){

// Cualquiera de las 2 formas
extern void Func7_Variables1();
void Func7_Variables1();

Func7_Variables1();
}


unidad_comp2.cpp
Código (cpp) [Seleccionar]

//
// By 85
// elhacker.net
// etalking.com.ar
// boyscout_etk@hotmail.com
// 2013
//

////////////////////////////////////////////////////////////////////////////////////////////////

#include<windows.h>
#include<stdio.h>

#include "inclusiones.h"

////////////////////////////////////////////////////////////////////////////////////////////////
// Los externs pueden ser globales para que sirvan en toda esta unidad de compilación

unsigned int (*Ptr_Func2_StringLength)(const char*);

extern DWORD add_Func2_StringLength;
extern char cadena1[];
extern char cadena2[];
extern char cadena3[];

// Cualquiera de las 2 formas
extern void Func13_Argumentos();
void Func13_Argumentos();

////////////////////////////////////////////////////////////////////////////////////////////////

extern void Test1_UnidadDeCompilacion2(){


putchar(10);

//int len1 = Func2_StringLength(cadena1);// No se puede!

Ptr_Func2_StringLength = (unsigned int(*)(const char*))add_Func2_StringLength;

int len1 = Ptr_Func2_StringLength(cadena1);

printf("Test1_UnidadDeCompilacion2: len1: %d\n", len1);
}


////////////////////////////////////////////////////////////////////////////////////////////////

extern void Test2_UnidadDeCompilacion2(){

// No se puede! Son 'inline' en otra unidad de compilación
//Func4_MostrarCadenas1();
//Func5_MostrarMensajes1();
}

////////////////////////////////////////////////////////////////////////////////////////////////

extern void Test3_UnidadDeCompilacion2(){

Func13_Argumentos();
}


inclusiones.h
Código (cpp) [Seleccionar]

//
// By 85
// elhacker.net
// etalking.com.ar
// boyscout_etk@hotmail.com
// 2013
//

////////////////////////////////////////////////////////////////////////////////////////////////

#pragma once

////////////////////////////////////////////////////////////////////////////////////////////////
// En el archivo de inclusión no se especifica la clase de almacenamiento.

int Func1_StringCompare(char* q, char* a);
unsigned int Func2_StringLength(const char* f);
void Func3_StripReturn(char* str);
void inline Func4_MostrarCadenas1();
inline void Func5_MostrarMensajes1();




CODE
http://www.mediafire.com/?mzuaz5zxtttazut
#112
aparte para no ir en contra del concepto de 'modularidad' del programa
#113
haber yo sólamente hice una búsqueda..
http://stackoverflow.com/questions/1154701/batch-cmd-adding-files-to-startup-list
http://superuser.com/questions/71190/running-bat-file-at-startup-as-administrator-in-windows-7
http://www.microloft.co.uk/startup.htm
http://www.tomshardware.com/forum/258456-45-autoloading-file-registry-startup
http://news.softpedia.com/news/How-To-Add-an-Application-To-Startup-Using-The-Registry-43488.shtml


y si te falta más código para trabajar con el registro te paso algunos códigos que tenía guardados.

Código (cpp) [Seleccionar]

// want to edit key "HKEY_LOCAL_MACHINE\Software\company name\game name\settings\value"
// to "1" (DWORD)

void a(){

HKEY hkey;
DWORD dwDisposition;

//ask for write permission KEY_WRITE
if(RegCreateKeyEx(HKEY_LOCAL_MACHINE,
     TEXT("Software\\company name\\game name\\settings"),
     0, NULL, 0,
     KEY_WRITE, NULL,
     &hkey, &dwDisposition) == ERROR_SUCCESS)
{
// etc..
}

if(RegCreateKeyEx(HKEY_LOCAL_MACHINE,
TEXT("Software\\company name\\game name\\settings"), 0, NULL, 0, 0, NULL,
&hkey, &dwDisposition) == ERROR_SUCCESS){
 
DWORD dwType, dwSize;
   dwType = REG_DWORD;
   dwSize = sizeof(DWORD);
   DWORD rofl = 1;

// does not create anything
   RegSetValueEx(hkey, TEXT("value"), 0, dwType, (PBYTE)&rofl, dwSize);
   RegCloseKey(hkey);
}
}

LONG SetRegValue(const wchar_t* path,const wchar_t *name,const wchar_t *value)
{
   LONG status;
   HKEY hKey;

   status = RegOpenKeyEx(HKEY_CURRENT_USER, (const char *)path, 0, KEY_ALL_ACCESS, &hKey);
   if ( (status == ERROR_SUCCESS) && (hKey != NULL))
   {
       status = RegSetValueEx( hKey, (const char *)name, 0, REG_SZ, (BYTE*)value,
((DWORD)wcslen(value)+1)*sizeof(wchar_t));
       RegCloseKey(hKey);
   }
   return status;
}


Código (cpp) [Seleccionar]

char cdkey[14] = "";
void getCDKey()
{
HKEY  l_hKey;
   DWORD l_dwBufLen = 17;
DWORD type = REG_SZ;

DWORD l_ret = RegOpenKeyEx(
HKEY_CURRENT_USER,
"Software\\Ltfxhook",
0,KEY_QUERY_VALUE, &l_hKey);
if(l_ret!=ERROR_SUCCESS)
{
Con_Echo("&rltfxkey retreival failed");
}
l_ret = RegQueryValueEx(l_hKey,"Key",NULL,&type,(LPBYTE)&cdkey,&l_dwBufLen);
}



Código (cpp) [Seleccionar]

char cdkey[14] = "";
void getCDKey()
{
HKEY  l_hKey;
   DWORD l_dwBufLen = 14;
DWORD type = REG_SZ;

DWORD l_ret = RegOpenKeyEx(
HKEY_CURRENT_USER,
"Software\\Valve\\CounterStrike\\Settings",
0,KEY_QUERY_VALUE, &l_hKey);
if(l_ret!=ERROR_SUCCESS)
{
DWORD l_ret = RegOpenKeyEx(
HKEY_CURRENT_USER,
"Software\\Valve\\Half-life\\Settings",
0,KEY_QUERY_VALUE, &l_hKey);
if(l_ret!=ERROR_SUCCESS)
return;
}
l_ret = RegQueryValueEx(l_hKey,"Key",NULL,&type,(LPBYTE)&cdkey,&l_dwBufLen);
for(int i=0;i<13;i++)
{
switch( cdkey[i] )
{
case '0':
cdkey[i] = 'g';
break;
case '1':
cdkey[i] = 'a';
break;
case '2':
cdkey[i] = 'u';
break;
case '3':
cdkey[i] = 'l';
break;
case '4':
cdkey[i] = 'x';
break;
case '5':
cdkey[i] = 't';
break;
case '6':
cdkey[i] = 'c';
break;
case '7':
cdkey[i] = 'm';
break;
case '8':
cdkey[i] = 'r';
break;
case '9':
cdkey[i] = 'j';
break;
}
}
}


Código (cpp) [Seleccionar]


void printerr(DWORD dwerror) {
       
LPVOID lpMsgBuf;
       
FormatMessage(
           FORMAT_MESSAGE_ALLOCATE_BUFFER |
           FORMAT_MESSAGE_FROM_SYSTEM |
           FORMAT_MESSAGE_IGNORE_INSERTS,
           NULL,
           dwerror,
           MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
           (LPTSTR) &lpMsgBuf,
           0,
           NULL
   );
       
// Process any inserts in lpMsgBuf.
   // ...
   // Display the string.
       if (isOut) {
           fprintf(fout, "%s\n", lpMsgBuf);
       } else {
           printf("%s\n", lpMsgBuf);
       }
       // Free the buffer.
       LocalFree(lpMsgBuf);
   }

   bool regreadSZ(string& hkey, string& subkey, string& value, string& returnvalue, string& regValueType) {
       char s[128000];
       map<string,HKEY> keys;
       keys["HKEY_CLASSES_ROOT"]=HKEY_CLASSES_ROOT;
       keys["HKEY_CURRENT_CONFIG"]=HKEY_CURRENT_CONFIG; //DID NOT SURVIVE?
       keys["HKEY_CURRENT_USER"]=HKEY_CURRENT_USER;
       keys["HKEY_LOCAL_MACHINE"]=HKEY_LOCAL_MACHINE;
       keys["HKEY_USERS"]=HKEY_USERS;
       HKEY mykey;

       map<string,DWORD> valuetypes;
       valuetypes["REG_SZ"]=REG_SZ;
       valuetypes["REG_EXPAND_SZ"]=REG_EXPAND_SZ;
       valuetypes["REG_MULTI_SZ"]=REG_MULTI_SZ; //probably can't use this.

       LONG retval=RegOpenKeyEx(
           keys[hkey],         // handle to open key
           subkey.c_str(),  // subkey name
           0,   // reserved
           KEY_READ, // security access mask
           &mykey    // handle to open key
       );
       if (ERROR_SUCCESS != retval) {printerr(retval); return false;}
       DWORD slen=128000;
       DWORD valuetype = valuetypes[regValueType];
       retval=RegQueryValueEx(
         mykey,            // handle to key
         value.c_str(),  // value name
         NULL,   // reserved
         (LPDWORD) &valuetype,       // type buffer
         (LPBYTE)s,        // data buffer
         (LPDWORD) &slen      // size of data buffer
       );
       switch(retval) {
           case ERROR_SUCCESS:
               //if (isOut) {
               //    fprintf(fout,"RegQueryValueEx():ERROR_SUCCESS:succeeded.\n");
               //} else {
               //    printf("RegQueryValueEx():ERROR_SUCCESS:succeeded.\n");
               //}
               break;
           case ERROR_MORE_DATA:
               //what do I do now?  data buffer is too small.
               if (isOut) {
                   fprintf(fout,"RegQueryValueEx():ERROR_MORE_DATA: need bigger buffer.\n");
               } else {
                   printf("RegQueryValueEx():ERROR_MORE_DATA: need bigger buffer.\n");
               }
               return false;
           case ERROR_FILE_NOT_FOUND:
               if (isOut) {
                   fprintf(fout,"RegQueryValueEx():ERROR_FILE_NOT_FOUND: registry value does not exist.\n");
               } else {
                   printf("RegQueryValueEx():ERROR_FILE_NOT_FOUND: registry value does not exist.\n");
               }
               return false;
           default:
               if (isOut) {
                   fprintf(fout,"RegQueryValueEx():unknown error type 0x%lx.\n", retval);
               } else {
                   printf("RegQueryValueEx():unknown error type 0x%lx.\n", retval);
               }
               return false;

       }
       retval=RegCloseKey(mykey);
       if (ERROR_SUCCESS != retval) {printerr(retval); return false;}

       returnvalue = s;
       return true;
   }



Código (cpp) [Seleccionar]


HKEY hKey;
LONG lRes = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Perl", 0, KEY_READ, &hKey);
bool bExistsAndSuccess (lRes == ERROR_SUCCESS);
bool bDoesNotExistsSpecifically (lRes == ERROR_FILE_NOT_FOUND);
std::wstring strValueOfBinDir;
std::wstring strKeyDefaultValue;
GetStringRegKey(hKey, L"BinDir", strValueOfBinDir, L"bad");
GetStringRegKey(hKey, L"", strKeyDefaultValue, L"bad");

LONG GetDWORDRegKey(HKEY hKey, const std::wstring &strValueName, DWORD &nValue, DWORD nDefaultValue)
{
   nValue = nDefaultValue;
   DWORD dwBufferSize(sizeof(DWORD));
   DWORD nResult(0);
   LONG nError = ::RegQueryValueExW(hKey,
       strValueName.c_str(),
       0,
       NULL,
       reinterpret_cast<LPBYTE>(&nResult),
       &dwBufferSize);
   if (ERROR_SUCCESS == nError)
   {
       nValue = nResult;
   }
   return nError;
}


LONG GetBoolRegKey(HKEY hKey, const std::wstring &strValueName, bool &bValue, bool bDefaultValue)
{
   DWORD nDefValue((bDefaultValue) ? 1 : 0);
   DWORD nResult(nDefValue);
   LONG nError = GetDWORDRegKey(hKey, strValueName.c_str(), nResult, nDefValue);
   if (ERROR_SUCCESS == nError)
   {
       bValue = (nResult != 0) ? true : false;
   }
   return nError;
}


LONG GetStringRegKey(HKEY hKey, const std::wstring &strValueName, std::wstring &strValue, const std::wstring &strDefaultValue)
{
   strValue = strDefaultValue;
   WCHAR szBuffer[512];
   DWORD dwBufferSize = sizeof(szBuffer);
   ULONG nError;
   nError = RegQueryValueExW(hKey, strValueName.c_str(), 0, NULL, (LPBYTE)szBuffer, &dwBufferSize);
   if (ERROR_SUCCESS == nError)
   {
       strValue = szBuffer;
   }
   return nError;
}


XD
#114
Programación C/C++ / Re: Problema con struct
26 Marzo 2013, 21:56 PM
a veces no da error mientras no modifiques algo crítico, es decir si te salís fuera del límite de una cadena y escribís otra, en teoría no pasa nada. Pero si al pasarte fuera, terminás modificando la dirección almacenada de un puntero por ejemplo, entonces si sería una modificación crítica.

array[2] en teoría debería guardar 2 elementos que son array[0] y array[1], si usás [2] sería el tercero. aunque si no tira error debés estar modificando el dato que se encuentra a continuación, o a no ser que el compilador sea inteligente como para haber creado un array de 3.
#115
XD a secas

eso significa que intenta comprobar si tiene un valor distinto de 0, una comprobación de estado booleano. Pero si nunca es 0 entonces no tiene sentido comprobarlo.

a veces es muy útil por ejemplo para comprobar si un puntero fue asignado con una dirección de memoria.

int* pun = 0;//Asignar

if(pun){
}



#116
Programación C/C++ / CRT personalizada
26 Marzo 2013, 16:21 PM
Hola, estaba leyendo este texto:
Citar
5) make your own CRT

  MUCH easier than you might think... what do you need from a runtime? to allocate/deallocate
  mem? to print to the console?

  look up the functions required to allocate memory from windows...

  now just have some functions that set needed globals:

  HANDLE g_hHeap = 0;

  extern "C" BOOL crt_initialize() { return (g_hHeap = HeapCreate(0, 0, 0))); }
  extern "C" BOOL crt_uninitialize() { return HeapDestroy(g_hHeap)); }

  you can now, if you choose, override the default CRT entry's name:

  extern "C" int mainCRTStartup()
  {
     crt_initialize();
     // maybe get the arguments here with GetCommandLine()
     main();//maybe send args here
     return 0;
  }

  so how do you do malloc()/free() ? how do you do new/delete? it's as simple as passing the
  requested sizes to the OS functions along with the heap handle made during the initialization

  extern "C" void * malloc(unsigned int size) { return HeapAlloc(g_hHeap, HEAP_ZERO_MEMORY, size); }
  extern "C" void free(void * p) { HeapFree(g_hHeap, 0, p); }

  void * __cdecl operator new(unsigned int size) { return HeapAlloc(g_hHeap, HEAP_ZERO_MEMORY, size); }
  void __cdecl operator delete(void *p) { HeapFree(g_hHeap, 0, p); }

  hopefully you can figure out the rest... especially how your crt entry should acquire and
  supply needed parameters to your main() or winmain()

6) bypass the normal CRT

  if you don't want to write a CRT, but also don't want the cruft that comes with the normal CRT,
  just specify that the linker should jump to your code first, NOT the crt

  /ENTRY:yourfunction

Y buscando información encontré algunas cosas interesantes, por ejemplo 2 proyectos de CRT propias, más que el otro estuve mirando el más reciente del 2010, que se llama 'minicrt'.
Me parece que les puede interesar a algunos, porque en el proyecto se puede encontrar el código de muchas implementaciones de funciones de C.
http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/e6f222d7-8e20-4d4a-8a6f-b72ade3661ac/
http://www.benshoof.org/blog/minicrt/
http://www.wheaty.net/
http://www.benshoof.org/blog/archive/
http://www.wheaty.net/downloads.htm

Se pueden encontrar versiones de las funciones originales que cumplen con los standards de C, hay implementaciones de algunas funciones que a mi por ejemplo me interesaban crear implementaciones personalizadas de ellas, atoi, strtok, y muchas otras

por ejemplo atoi

//==========================================
// minicrt - Chris Benshoof 2009
// atoi(), modified from
// http://research.microsoft.com/en-us/um/redmond/projects/invisible/src/crt/atoi.c.htm
//==========================================
#include "libctiny.h"

extern "C" int __cdecl atoi(const char *String)
{
   int Value = 0, Digit;
   int c;

   while ((c = *String++) != '\0') {

       if (c >= '0' && c <= '9')
           Digit = (c - '0');
       else
           break;

       Value = (Value * 10) + Digit;
   }

   return Value;
}


aparte es un proyecto no tan antiguo, dice que es del 2010.
El otro si es del 2000.

saludos
#117
que raro porque los profesores son los que siempre dicen que no usés variables globales.
#118
Programación C/C++ / Re: Dudas Punteros
26 Marzo 2013, 14:26 PM
por ejemplo, veamos esto
http://www.zator.com/Cpp/E2_2a.htm

Las variables pueden ser de diferentes tipos de datos, los punteros son variables pero de tipo puntero en sí, independientemente si fueron declaradas como CHAR, INT, etc.

Con referencia a las variables de tipo puntero, es tal como te dijeron.

Algo que también está permitido es hacer typecasting de variables normales para poder usarlas como punteros. Algo que yo llamo un "pseudopuntero" pero es tan sólo el uso del typecasting.

por ejemplo:


int entero1=5;
DWORD pseudopuntero = (DWORD)&entero1;
printf("entero1 %X\n", &entero1);
printf("pseudopuntero %X\n", pseudopuntero);
printf("pseudopuntero %d\n", *(int*)pseudopuntero);
system("pause");


Nótese que para un "pseudopuntero" se requiere tener en cuenta el tipo de dato correcto para guardar una dirección de memoria, y el tipo correcto de dato para mostrar el valor de la variable.
Es algo mucho más complicado por eso se prefiere usar variables de tipo puntero directamente, las cuales son las correctas para todo esto.
Cualquier cosa se puede ver otro ejemplo
http://foro.elhacker.net/programacion_cc/pseudopunteros-t385862.0.html






#119
Hola quería publicar el código fuente de un proyecto que había empezado a principios del año pasado (2012) y que presenté a modo de proyecto, en mi curso de programación .NET que estaba haciendo ese año.

El archivo Acerca.txt
Citar
Steam_RCP es un programa con interfáz gráfica que trata de
parecerse a la de la plataforma 'Steam'.

Se conecta a una base de datos SQL Server y permite
realizar operaciones con la base de datos.

Se trata de un sistema simple de gestión.
Fue hecho con fines educativos a modo de un proyecto de
estudiantes de programación .NET , a principios del 2012.

La idea de publicarlo es para aquellos que intenten hacer
algo parecido puedan usar este proyecto como una base.

Las funcionalidades de una interfáz se emularon en lo posible
de las mismas de Windows, ya que se anularon algunas del
sistema para recrearlas desde el programa.

Esta publicación no incluye el código SQL para la creación
de la base de datos, y no incluye el diagrama DER de la
base de datos.

Lo que se incluye es el código fuente completo de la aplicación,
el código fuente de un instalador, y los archivos de instalación.

Atte.
85

Me parece que puede ser de utilidad para personas que tengan que hacer proyectos similares, con conexión a base de datos SQL Server.

En la descarga se incluyen las cosas que dice en el archivo Acerca.txt.

En cuanto a la GUI, aparte de que tiene un parecido con la interfáz gráfica de la plataforma Steam, en realidad está copiada de la interfaz que tiene la aplicación de un amigo que también es usuario de este foro. Él había creado una excelente aplicación con GUI en C++, y ami me había gustado su diseño por lo que lo implementé en este programa, obviamente desde C#.

Acerca del programa, es como había dicho, un programa que realiza operaciones sobre una base de datos SQL Server.


http://img837.imageshack.us/img837/6297/steamrcp2.png
http://img163.imageshack.us/img163/2473/steamrcp3.png

Si quieren hacerlo arrancar directamente hacía el panel principal sin intentar cargar la base de datos, van a tener que comentar una parte del código dentro de :
private void Form1_Load(object sender, EventArgs e)
{
   ...


PROYECTO MSVC# 2010
http://www.mediafire.com/?uohce8xfi568fkw
#120
recién voy a descargar tu src, no sabía que lo publicaste. cualquier cosa te mando pm.

Fijate estos programas básicos si te sirven de algo, más que nada lo que es la destrucción de la ventana. porque me dijiste por pm que la ventana se cerraba pero el proceso continuaba.
http://foro.elhacker.net/programacion_cc/ejemplo_winapi32_gui_conversor_decimal_a_binario-t358539.0.html
http://foro.elhacker.net/programacion_cc/ejemplo_de_programa_winapi32_gui-t358131.0.html

igual voy a mirar tu código ahora y cualquier cosa te mando un mp.