[Last Call] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

Registry Functions

Posted on 2004-11-03
31
Medium Priority
?
526 Views
Last Modified: 2010-04-05
hi, I've created a Registry Function that uses all the functions that will only use 1 line of code to call the function, I need this neating up, trimming and adding more addons 2 the Function.

I need these below adding and if there is any more registry functions that can be added please add them 2 the Function.
WriteBool
ReadBool

maybe KeyExist, ValueExists, reading & writing binary to the registry.


so this will be a fully working Function, which all the Registry Entrys allowed.

=======
to Call the Function = Registry('ReadString','HKEY_LOCAL_MACHINE','\Software\Client\','format','');
=======
function Registry(func:string;root:string;path:string;setting:string;write:string):string;
begin
With TRegistry.Create do try

    if root = 'HKEY_CLASSES_ROOT' then
      RootKey:=HKEY_CLASSES_ROOT
    else if root = 'HKEY_CURRENT_USER' then
      RootKey:=HKEY_CURRENT_USER
    else if root = 'HKEY_LOCAL_MACHINE' then
      RootKey:=HKEY_LOCAL_MACHINE
    else if root = 'HKEY_USERS' then
      RootKey:=HKEY_USERS
    else if root = 'HKEY_CURRENT_CONFIG' then
      RootKey:=HKEY_CURRENT_CONFIG;
    OpenKey(path,false);

    if func = 'ReadString' then
      result := ReadString(setting)
    else if func = 'WriteString' then
      WriteString(setting,write)
    else if func = 'WriteInteger' then
      WriteInteger(setting,strtoint(write))
    else if func = 'DeleteValue' then
      DeleteValue(setting)
    else if func = 'DeleteKey' then
      DeleteKey(path)

finally
  Free;
end;
end;
=======

do u understand what I'm wanting 2 achieve? from this function? an all in 1 Registry Function that works with just 1 line of code to call it.

please could u solve this problem for me, I've done 80% of it, just need the others adding.

Sal.
0
Comment
Question by:SaLz
  • 10
  • 9
  • 5
  • +3
27 Comments
 
LVL 6

Accepted Solution

by:
rbohac earned 1200 total points
ID: 12488011
Set the default return value to ''
Added " if valueexists" to the read functions
added read/write bool
modified the call to open key so a "if keyexists" call is not needed.

This function still leaves a lot to be desired as far ar error checking goes though.

Also, it won't be easy (if it is even possible at all) to pass the binary data through strings like this

function Registry(func:string;root:string;path:string;setting:string;write:string):string;
begin
Result := '';
With TRegistry.Create do try

   if root = 'HKEY_CLASSES_ROOT' then
     RootKey:=HKEY_CLASSES_ROOT
   else if root = 'HKEY_CURRENT_USER' then
     RootKey:=HKEY_CURRENT_USER
   else if root = 'HKEY_LOCAL_MACHINE' then
     RootKey:=HKEY_LOCAL_MACHINE
   else if root = 'HKEY_USERS' then
     RootKey:=HKEY_USERS
   else if root = 'HKEY_CURRENT_CONFIG' then
     RootKey:=HKEY_CURRENT_CONFIG;
   if OpenKey(path,false)then
     begin

     if func = 'ReadString' then
      begin
       if ValueExists(Setting) then
         result := ReadString(setting)
       end
     else if func = 'ReadInteger' then
       begin
       if ValueExists(Setting) then
         Result := IntToStr(ReadInteger(setting))
       end
     else if func = 'ReadBool' then
       begin
       if ValueExists(Setting) then
         Result := BoolToStr(ReadBool(setting))
       end

     else if func = 'WriteString' then
       WriteString(setting,write)
     else if func = 'WriteInteger' then
       WriteInteger(setting,strtoint(write))
     else if func = 'WriteBool' then
       WriteBool(setting,strtobool(write))

     else if func = 'DeleteValue' then
       DeleteValue(setting)
     else if func = 'DeleteKey' then
       DeleteKey(path)
     end;
finally
 Free;
end;
end;
0
 
LVL 17

Assisted Solution

by:mokule
mokule earned 200 total points
ID: 12488338
Hi,
Let me tell You that the idea looks to me a little bit questionable.
There are also such functions as.
 ReadCurrency();
 ReadBinaryData();
 ReadDate();
 ReadDateTime();
 ReadFloat();
 ReadTime();

You'll have a lot work with converting some of their result to string.
You'll also need default value setting rather then empty string in case absent value, I think.
I don't get why You want
to Call the Function = Registry('ReadString','HKEY_LOCAL_MACHINE','\Software\Client\','format','');
and not simply
Registry('ReadString',HKEY_LOCAL_MACHINE,'\Software\Client\','format','');

Not to mention the slowness of the solution.
0
 
LVL 3

Assisted Solution

by:Sabre
Sabre earned 600 total points
ID: 12494410
I'm afraid Mokule is right.  The whole method you've gone for serves no real purpose and is not the best way to go about it in terms of debugging, speed of the routine, etc.

What you might be better doing is looking at http://www.swissdelphicenter.ch/en/showcode.php?id=2008

It gives full source code for a set of registry functions that do not use the TRegistry unit which reduces overall program size, etc.  You will be able to combine many of the functions into one from the given source if that is really what you want to do.
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 2

Author Comment

by:SaLz
ID: 12495560
~~~~~~~~
I don't get why You want
to Call the Function = Registry('ReadString','HKEY_LOCAL_MACHINE','\Software\Client\','format','');
and not simply
Registry('ReadString',HKEY_LOCAL_MACHINE,'\Software\Client\','format','');

Not to mention the slowness of the solution.
~~~~~~~~
what are u talking about? I was telling u how I called the function lol, "to call the function =" was only to tell u how I called the function, like 2x2 = 4 the 2x2 was only showing u what I was saying, after the = is the function.

tell me why u think the method is 'slowness' how can I make it faster?

the method serves a great purpose in what am achieving, this will stop me having to keep editing and adding and compiling a NEW EXE , I can just edit a simple xml file :D with out doing anything else 2 the EXE, just a simple XML call, put the "calls" into the XML and away we go, its that simple, it gonna be used far more than just in xml, that was just an example of what a universal function could be like.

why u think I wanted to make a Function for the registry? its going to be 1 Function that can do all the functions to do with the registry with just 1 line of code? don't that sound amazing 2 u, than having functions all over and having 2 keep adding and deleting and moving and then recompiling the exe, beleave me, its a wast of time keep recompiling the code each time.

and that link u posted Sabre is something like what am trying 2 do with TRegistry, but the thing is, this isn't quite what am after, this may be on the same lines and it gives me the other info like..

    RegGetExpandString(HKEY_CURRENT_USER, 'Software\My Company\Test\foo\bar\TestExpandString', s);
    RegGetDWORD(HKEY_CURRENT_USER, 'Software\My Company\Test\foo\bar\TestDword', d);
    RegGetBinary(HKEY_CURRENT_USER, 'Software\My Company\Test\foo\bar\TestBinary', s);

but its not 1 Function with only 1 line of code which I've achived with the source I posted above, I just need the list of other TRegistry Functions and how 2 work them with the right function so if its string to boolean then it will be

Write..
     else if func = 'WriteBool' then
       WriteBool(setting,strtobool(write))

Read..
     else if func = 'ReadBool' then
       begin
       if ValueExists(Setting) then
         Result := BoolToStr(ReadBool(setting))
       end

I thank rbohac for giving me the work out code, its that simple guys the function name, then the function its self just like above. in/out.

rbohac u got anymore workout methods?

so if u could find other functions and work out the codin like strtobool() and others,

Thanks
Sal.
0
 
LVL 2

Author Comment

by:SaLz
ID: 12495737
this is what am talking about, the link u posted sabre, its got loads of functions, and it quite a lenghy Functions.

this is just to delete a value :S do u really need all that code just 2 delete a a value?
~~~
function RegDelKey(RootKey: HKEY; Name: String): boolean;
var
  SubKey: String;
  n: integer;
  hTemp: HKEY;
begin
  Result := False;
  n := LastPos('\', Name);
  if n > 0 then
  begin
    SubKey := Copy(Name, 1, n - 1);
    if RegOpenKeyEx(RootKey, PChar(SubKey), 0, KEY_WRITE, hTemp) = ERROR_SUCCESS then
    begin
      SubKey := Copy(Name, n + 1, Length(Name) - n);
      Result := (RegDeleteKey(hTemp, PChar(SubKey)) = ERROR_SUCCESS);
      RegCloseKey(hTemp);
    end;
  end;
end;
~~~

when I look at that am thinkin, umm all I want 2 do is delete a value, whats with all that code?

what I have used for delete value is.. compared 2 the code above,does it look faster, much more efficient? or is my way allot smoother and better?
~~~
     else if func = 'DeleteValue' then
       DeleteValue(setting)
~~~

Sal.
0
 
LVL 2

Author Comment

by:SaLz
ID: 12495790
am cutting out the junk, and shorting the code down 2 the bare minimum, simplistity, thats the key,

true, I did start at first with the same long ass functions, then I thought hmm, how can I make this better, how can I cut down the code and make it smaller, like most things, this is what I do, people always make easier faster ways of doing the same job.

just depends how fast and smooth u want 2 get 2 the finishin line.

Sal.
0
 
LVL 2

Author Comment

by:SaLz
ID: 12495952
its funny, cos I remember a wile back I started out with something like this
~~~
procedure TForm1.Registry(Path:string);
Var
  Reg: TRegistry;
begin
 Reg:=TRegistry.Create;
  try
   Reg.RootKey:=HKEY_LOCAL_MACHINE;
    if not Reg.OpenKey(DKey+Path,False) then
~~~

then I thought, hmm looks a bit messy, don't need all that txt, so I shortened it,
~~~
procedure TForm1.Registry(Path:string);
begin
With TRegistry.Create do try
     RootKey:=HKEY_LOCAL_MACHINE
     if OpenKey(path,false)then
     begin
~~~
took out the var, took out the reg, just cut out all the junk and neatened it up, this is what I do with all my code, just taking out the junk, and keeping it real.

so this is why I'm after registry method functions.

Sal.
0
 
LVL 3

Assisted Solution

by:Sabre
Sabre earned 600 total points
ID: 12496058
>am cutting out the junk, and shorting the code down 2 the bare minimum, simplistity, thats the key,

Sorry, but using the TRegistry unit does not cut the code to the bare minimum as you say, and if i remember correctly the TRegistry unit also uses the IniFiles unit.  What do you think sits behind  the line of code you gave of..

else if func = 'DeleteValue' then
      DeleteValue(setting)

It links to a function within the TRegistry unit, so to say that it is better is down to a programmers methodology and not compactness of code.

the link i provided is for a "lightweight" set of functions for the registry that use the Win API to work with the registry.  This makes for a smaller exe file size as the functions called are built into windows.

As for additional code within many of the functions, they serve as error trapping methods.

Do a simple test - just create an exe file that uses your line of code:

else if func = 'DeleteValue' then
      DeleteValue(setting)

compile it and note the size - they remove the TRegistry unit and use the same function from the source code i pointed out - you'll see a difference in exe file size for a start.

0
 
LVL 6

Expert Comment

by:rbohac
ID: 12496357
I'm willing to help, but I'm not willing to write all of the ode for you. Check the Delphi help file. It has all of the functions listed in there? If you need someone to write a program for you, please check out a site like rentacoder.com

Are you trying to make the exe size smaller, or are you just trying to make it easier to parse data from an XML file like you said earier? If that is the case then this makes sense.

And yes, Sabre and mokule are both correct. This is not as efficient. I big reason for this is the fact that you are doing a bunch of unnecessary type conversions. (Like inttostr then strtoint) just to read and/or write the data.
0
 
LVL 2

Author Comment

by:SaLz
ID: 12496358
ok, stop being sark, ur being perfetic..

the junk refers 2 the none essential code, that only adds more lines, and makes the code look messy.
cutting dow the the bare minimum is the skill of everythign that we do, when running a mile we always try and run that extra bit faster than the day before, just 2 cut off that extra edge, am I right or am I right.

~~
>Sorry, but using the TRegistry unit does not cut the code to the bare minimum as you say, and if i remember correctly the TRegistry unit also uses the IniFiles unit.  What do you think sits behind  the line of code you gave of..
~~
what on earth are u talking about, ffs why are u wasting ur type like this rofl!!, see this is what I mean about wasted text, cut out the junk and get real.

rofl if u call that link u send me 'lightweight' I would say thats 2 messy, the functions there, don't get me wrong, but for me, I don't like mess, and I dont like wast, its that simple, but it does weigh a ton in text tho when u stick it into 2 the form lol.

and about the error traps, look in my functions there will be error traps, but they wont be in every damn function they will be called only once from 1 function saves time and effort.

and about..
~~
Do a simple test - just create an exe file that uses your line of code:

else if func = 'DeleteValue' then
      DeleteValue(setting)

compile it and note the size - they remove the TRegistry unit and use the same function from the source code i pointed out - you'll see a difference in exe file size for a start.
~

about the exe size, get real man, what are u on? what u taking? look the exe size doesn't make a diffrence 2 me, if it was 500k or 10MB, size of the exe just doesn't matter, I'll compress it if I really need and want 2, its someone else problem.

but the neatness and compactness of the internal code thats where I want 2 cut down as many lines as I can, when u have 10-20,000 lines of code, do u really want all that none essential junk just messing up ur code lengh. u really got 2 put more effort into a question that 2 keep on complaining, just answer the questions, stop being a jerk.

u got 2 understand when a person is coding allot of code, 10-20,000 they need 2 make everything as compact as they can wile still having a working functions.

please just stop being a jerk about all this, Sabre.
 
Sal.
0
 
LVL 2

Author Comment

by:SaLz
ID: 12496402
hey rbohac hows things, u doing aight?

u don't got 2 write all the code, there is 2 much code for u 2 write for me anyway, all I need from u and this question is the same priniple as u have done before.

Write..
     else if func = 'WriteBool' then
       WriteBool(setting,strtobool(write))

Read..
     else if func = 'ReadBool' then
       begin
       if ValueExists(Setting) then
         Result := BoolToStr(ReadBool(setting))
       end

u did amazing with that code, just what I'm wanting, simple convertions like that for the functions.

if this is a wast 2 u, then its my wast, but for me, this aint a wast, 1 Function, 1 Line of Code, thats heaven for me :D

Sal.
0
 
LVL 6

Expert Comment

by:rbohac
ID: 12496409
Why do you care about code length so much? Sabre is not being a jerk and is offering some really good advice. Error trapping code is not "junk".

Also, please stop replacing "u" for you, 2 for to, and using other common chat/aim shortcuts along with profane language. This is not a chat room.

If you don't crae to respect the advice from experts, then don't ask.
0
 
LVL 6

Assisted Solution

by:rbohac
rbohac earned 1200 total points
ID: 12496451
Those are simple data types. You are going to run into some serious problems with the other data types though such as binary data or date/time conversions. Especially if you don't have error checking.


Have a look at:

DateToStr
DateTimeToStr
StrToDate
StrToDateTime
FloatToStr
0
 
LVL 2

Author Comment

by:SaLz
ID: 12496543
>And yes, Sabre and mokule are both correct. This is not as efficient. I big reason for this is the fact that you are doing a bunch of unnecessary type conversions. (Like inttostr then strtoint) just to read and/or write the data.

how can this be unnecessary? could u tell me a easier way and shorter way wile still keeping a working function I would like 2 see it, please show me it if your doubting it.

to read a value in the registry all I need is from my function..
result := ReadString(setting)

to write a value into the registry ann I need is this..
WriteString(setting,write)

to call the functions..
Registry('ReadString','HKEY_LOCAL_MACHINE','\Software\Client\','RegVal','');

how unnecessary can that be, just 1 line of code, omg u can't get better than that rofl!, but I would still like u 2 show me a easier way of using 1 Function with 1 line of code 2 call it,

please stop complaining, if u have a problem tell me how I can solve it, not 2 have a girly mown about it.

but what problem with the function? tell me if u think there is a problem with the function tell me and I will try it out, but please less complaining and more solutions, its like ur acting like a butch of girls, if ur female then am sorry, u are acting how u should be acting :D always wanting 2 put a guy down and taking his money, rofl

Sal.
0
 
LVL 3

Expert Comment

by:Sabre
ID: 12496607
Interesting points SaLz  - all completely wrong but then i have a feeling you have your opinion and all other programmers are wrong regardless.  I could of course address the issues you raised, but i prefer not to lower myself to that type of standard.

I'll offer you "good luck" with your endevours and perhaps when you gain a little more experience with delphi in the future you'll understand what rbohac and myself have been trying to point out to you.

0
 
LVL 6

Expert Comment

by:rbohac
ID: 12496688
I do not question your need or use of the function. I can see your point in the way you want to use it.

Nobody is complaining. We are offering advice.

"always wanting 2 put a guy down and taking his money". Nobody in this forum gets paid to offer you advice. I do not understand what your intentions are by making this statement. We are doing this for free.
0
 
LVL 2

Author Comment

by:SaLz
ID: 12496693
for what its worth rbohac, there mostly strings and intergers, bit of binary in the registry, thats the best thing about this function u can do the final code and filtering with the code, all it does is calls the data out of the registry. and displays it saying here is the data, do as u wish with me.

like for example, something easier like
edit1.text:=Registry();
trackbar1.position:=strtoint(Registry());

all the other stuff is done at the point where am coding the exe right down at the bottom of the form.

just a method, of writing and reading of the registry. in 1 Functions with a call of 1 line.

Sal.
0
 
LVL 6

Expert Comment

by:rbohac
ID: 12496701
Well, I look forward to you splitting the points, and with you the best of luck also.
0
 
LVL 3

Assisted Solution

by:Sabre
Sabre earned 600 total points
ID: 12496826
SaLz - as rbohac said, Nobody is complaining. We are offering advice.

So if you take a moment to read this you'll see that no one is attacking you - just offering advice.  You can choose to ignore the advice or learn from it.

You mentioned the amount of code the source i pointed out puts into your form - here is a solution:

By using the TRegistry unit in the uses section of your form, it instructs delphi to compile into the program the Tregistry unit and any other units that it uses.

The source i point out, should be placed into its own unit and saved off as SaLzReg.pas for example.  Now instead of using TRegistry in the uses clause, you can use SaLzReg.pas.  

This will then allow you to use a single line of code within your form such as RegSetString(HKEY_CURRENT_USER, 'Software\My Company\Test\foo\bar\TestString', 'TestMe');


Of course, you can always add to or change the functions within SaLzReg.pas to suit your needs - but the main point is that they will at least offer you a good place to start and will give you the tidy code that you look for.

As i said, you can ignore the advice and continue the same type of postings - but if you take a look, you'll find that sometimes advice from experts does work ;)

0
 
LVL 6

Expert Comment

by:rbohac
ID: 12496833
Old enough that I've never used such acronyms such as "ROFL", "u", "2", or resorted to name calling in a professional discussion. Quite intersting.

Anyway. As far as the binary conversion goes: You will probably have issues with the string to binary conversion, and you may have to escape the data before you write it into string.

You will also need to standardize on a date format, or always write the date using datetimetostr and read it using strtodatetime
0
 
LVL 6

Assisted Solution

by:rbohac
rbohac earned 1200 total points
ID: 12496893
Sabre, good point.

You can also write overloaded functions to do it, so that it appears as though you are calling one function: examples:

procedure WriteRegistry(root:string;path:string;setting:string;write:string); overload;
procedure WriteRegistry(root:string;path:string;setting:string;write:integer); overload;
procedure WriteRegistry(root:string;path:string;setting:string;write:real); overload;
procedure WriteRegistry(root:string;path:string;setting:string;write:boolean); overload;
procedure WriteRegistry(root:string;path:string;setting:string;write:TDateTime); overload;
etc..


that way you only call the one function, and delphi will know enough to call the particular stub function based on the data type of the "write" variable.
0
 
LVL 3

Expert Comment

by:Sabre
ID: 12496938
Exactly rbohac - and takes Salz one step closer to code that is Readable, Re-usable and reliable - the three R's a programmer strives for :)
0
 
LVL 2

Author Comment

by:SaLz
ID: 12497181
~~~~~~rbohac
>Why do you care about code length so much? Sabre is not being a jerk and is offering some really good advice. Error trapping code is not "junk".
Also, please stop replacing "u" for you, 2 for to, and using other common chat/aim shortcuts along with profane language. This is not a chat room.
If you don't crae to respect the advice from experts, then don't ask.
~~~~~~~~~

its ok, rbohac, u did ur best, u can't help it, u couldn't understand, u poor thing, but u will understand it in a moment.

the reason why I really want 2 compact the data, its because I really do just hate wast, why do u think I have a 8pack? I hate wast for real, I work out go gym, wast is a killer and when u don't need it why have it there, just like FAT!, get toned, get them girls, take out the non combatants, there is always a easier and simpler way of doing things, the function works perfect, and its so small, and it can be edited externally as well, so the users has more control.

this link..
http://www.swissdelphicenter.ch/en/showcode.php?id=2008

to me its just a joke, its just 2 large for what am doing, each programmer uses what they think will work best for them, for me there are 2 many functions that just don't need 2 be there, I'm not gonna complain about it and say his code isn't right, his code is fine, its just not gonna be acceptable in my code, I hate wast and I hate messy code, its that simple.

I've just moved everything into 1 function for simplicity, and about error trapping, this is what I mean, just stop being girls, moaning all the time about something that is already within the code, I just took out something simple out of my code for u guys 2 understand, but u couldn't even understand the simplest.

but in the end, I think this question went really well, I got quite allot of info on the subject, but 2 many posts complaining, get 2 many wedges at school?

well besides that, u guys did an amazing job for what u could have done in half the time :D this is another thing about getting rid of the junk, compacting the text and having the raw data that works wonders, but like before, u wont understand this, its going right over ur heads :D woosh there it goes, lol

cya
Sal.
0
 
LVL 2

Author Comment

by:SaLz
ID: 12498332
>The source i point out, should be placed into its own unit and saved off as SaLzReg.pas for example.  Now instead of using TRegistry in the uses clause, you can use SaLzReg.pas.  
This will then allow you to use a single line of code within your form such as RegSetString(HKEY_CURRENT_USER, 'Software\My Company\Test\foo\bar\TestString', 'TestMe');
~~~
ok, Sabre, there.. thats the only real good answer u have posted within this question, even tho I'm using the that method with my project, I got 2, only way of keeping the code 2 a limit, its just good 2 know we on the same page, u posted a good answer there, gj, but this time try and get closer 2 the question, which is at the top of the page, if u can't do it then say so.

now with the 3 R's, I 2, aim for that, use it in my projects, lets break it down.
Readable: taking out the junk, all the none essentail text, having it clean, smoonth, simple and organized.
Re-usable: having 1 function that does all the Functions within just 1 Function that will be called with 1 Line of Code for every known action with out editing the Script in anyway once finished.
Reliable: make sure it works everytime, put in a backcheck, error trap, bring smoothness and quickness, fastest route 2 a point.

rbohac, u 2 did a good answer, damn I was getting worried u 2 would be complaining all night and not getting down 2 solving some problems with code, lol but in the end u did some code, but it did take u a wile 2 pump out some code even tho the code u posted is almost miles from the question I asked, but u are on the right tracks, keep it up.

all this text on this page for something that is so small, amazing how much waste was typed and still nout :D

Keep up the kind of good work? :S

Sal.
0
 

Expert Comment

by:erin010
ID: 12506669
Unbelivable. I have never seen such language on EE before. I am simply shocked that a software developer could use that kind of a language in a professional forum.
0
 
LVL 6

Assisted Solution

by:rbohac
rbohac earned 1200 total points
ID: 12507180
Sorry about that. wrong window
0
 

Expert Comment

by:WesLennon
ID: 12525059
Trust me SaLz, I can see all deleted comments.  This questioin will not be deleted.
0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

Question has a verified solution.

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

In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
Exchange organizations may use the Journaling Agent of the Transport Service to archive messages going through Exchange. However, if the Transport Service is integrated with some email content management application (such as an anti-spam), the admin…
Loops Section Overview
Suggested Courses

830 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